2020-03-13 18:44:58 +11:00
using System ;
using System.Data.Common ;
using System.Reflection ;
2020-02-24 16:18:47 +01:00
using Microsoft.AspNetCore.Hosting ;
using Microsoft.AspNetCore.Http ;
2020-03-16 14:02:08 +01:00
using Microsoft.Extensions.Configuration ;
2020-02-18 08:32:06 +01:00
using Microsoft.Extensions.DependencyInjection ;
2020-02-27 11:48:38 +01:00
using Microsoft.Extensions.Hosting ;
2020-02-25 08:56:58 +01:00
using Umbraco.Composing ;
2020-03-16 14:02:08 +01:00
using Umbraco.Configuration ;
2020-02-24 16:18:47 +01:00
using Umbraco.Core ;
using Umbraco.Core.Cache ;
2020-03-13 18:44:58 +11:00
using Umbraco.Core.Composing ;
2020-02-24 16:18:47 +01:00
using Umbraco.Core.Configuration ;
2020-03-19 18:43:39 +01:00
using Umbraco.Core.Configuration.UmbracoSettings ;
2020-02-24 16:18:47 +01:00
using Umbraco.Core.IO ;
using Umbraco.Core.Logging ;
using Umbraco.Core.Logging.Serilog ;
2020-03-13 18:44:58 +11:00
using Umbraco.Core.Persistence ;
2020-02-25 08:56:58 +01:00
using Umbraco.Core.Runtime ;
2020-02-18 08:32:06 +01:00
namespace Umbraco.Web.BackOffice.AspNetCore
{
2020-03-13 18:44:58 +11:00
2020-03-23 15:50:01 +11:00
2020-02-18 08:32:06 +01:00
public static class UmbracoBackOfficeServiceCollectionExtensions
{
2020-02-24 16:18:47 +01:00
2020-03-17 17:56:00 +01:00
public static IServiceCollection AddUmbracoConfiguration ( this IServiceCollection services )
{
var serviceProvider = services . BuildServiceProvider ( ) ;
var configuration = serviceProvider . GetService < IConfiguration > ( ) ;
var configsFactory = new AspNetCoreConfigsFactory ( configuration ) ;
var configs = configsFactory . Create ( ) ;
2020-03-19 18:43:39 +01:00
2020-03-17 17:56:00 +01:00
services . AddSingleton ( configs ) ;
return services ;
}
2020-03-23 15:50:01 +11:00
2020-03-13 18:44:58 +11:00
/// <summary>
/// Adds the Umbraco Back Core requirements
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
/// <remarks>
/// Must be called after all services are added to the application because we are cross-wiring the container (currently)
/// </remarks>
public static IServiceCollection AddUmbracoCore ( this IServiceCollection services )
{
if ( ! UmbracoServiceProviderFactory . IsActive )
throw new InvalidOperationException ( "Ensure to add UseUmbraco() in your Program.cs after ConfigureWebHostDefaults to enable Umbraco's service provider factory" ) ;
var umbContainer = UmbracoServiceProviderFactory . UmbracoContainer ;
2020-03-13 19:10:21 +11:00
return services . AddUmbracoCore ( umbContainer , Assembly . GetEntryAssembly ( ) ) ;
}
public static IServiceCollection AddUmbracoCore ( this IServiceCollection services , IRegister umbContainer , Assembly entryAssembly )
{
services . AddSingleton < IHttpContextAccessor , HttpContextAccessor > ( ) ;
CreateCompositionRoot ( services ) ;
2020-03-13 18:44:58 +11:00
// TODO: Get rid of this 'Current' requirement
var globalSettings = Current . Configs . Global ( ) ;
var umbracoVersion = new UmbracoVersion ( globalSettings ) ;
2020-03-13 19:10:21 +11:00
// TODO: Currently we are not passing in any TypeFinderConfig (with ITypeFinderSettings) which we should do, however
// this is not critical right now and would require loading in some config before boot time so just leaving this as-is for now.
var typeFinder = new TypeFinder ( Current . Logger , new DefaultUmbracoAssemblyProvider ( entryAssembly ) ) ;
2020-03-13 18:44:58 +11:00
var coreRuntime = GetCoreRuntime (
Current . Configs ,
umbracoVersion ,
Current . IOHelper ,
Current . Logger ,
Current . Profiler ,
Current . HostingEnvironment ,
2020-03-13 19:10:21 +11:00
Current . BackOfficeInfo ,
typeFinder ) ;
2020-03-13 18:44:58 +11:00
var factory = coreRuntime . Boot ( umbContainer ) ;
2020-02-18 08:32:06 +01:00
return services ;
}
2020-03-13 18:44:58 +11:00
private static IRuntime GetCoreRuntime ( Configs configs , IUmbracoVersion umbracoVersion , IIOHelper ioHelper , ILogger logger ,
2020-03-13 19:10:21 +11:00
IProfiler profiler , Core . Hosting . IHostingEnvironment hostingEnvironment , IBackOfficeInfo backOfficeInfo ,
ITypeFinder typeFinder )
2020-03-13 18:44:58 +11:00
{
var connectionStringConfig = configs . ConnectionStrings ( ) [ Constants . System . UmbracoConnectionName ] ;
var dbProviderFactoryCreator = new SqlServerDbProviderFactoryCreator (
connectionStringConfig ? . ProviderName ,
DbProviderFactories . GetFactory ) ;
// Determine if we should use the sql main dom or the default
2020-03-23 15:50:01 +11:00
var globalSettings = configs . Global ( ) ;
var connStrings = configs . ConnectionStrings ( ) ;
var appSettingMainDomLock = globalSettings . MainDomLock ;
2020-03-13 18:44:58 +11:00
var mainDomLock = appSettingMainDomLock = = "SqlMainDomLock"
2020-03-23 15:50:01 +11:00
? ( IMainDomLock ) new SqlMainDomLock ( logger , globalSettings , connStrings , dbProviderFactoryCreator )
2020-03-13 18:44:58 +11:00
: new MainDomSemaphoreLock ( logger , hostingEnvironment ) ;
var mainDom = new MainDom ( logger , hostingEnvironment , mainDomLock ) ;
var coreRuntime = new CoreRuntime ( configs , umbracoVersion , ioHelper , logger , profiler , new AspNetCoreBootPermissionsChecker ( ) ,
hostingEnvironment , backOfficeInfo , dbProviderFactoryCreator , mainDom , typeFinder ) ;
return coreRuntime ;
}
2020-02-25 08:56:58 +01:00
2020-03-16 14:02:08 +01:00
public static IServiceCollection CreateCompositionRoot (
this IServiceCollection services ,
IHttpContextAccessor httpContextAccessor ,
IWebHostEnvironment webHostEnvironment ,
IHostApplicationLifetime hostApplicationLifetime ,
2020-03-17 17:56:00 +01:00
Configs configs )
2020-02-24 16:18:47 +01:00
{
2020-03-16 19:14:04 +01:00
var hostingSettings = configs . Hosting ( ) ;
var coreDebug = configs . CoreDebug ( ) ;
var globalSettings = configs . Global ( ) ;
2020-02-24 16:18:47 +01:00
2020-03-18 19:17:51 +01:00
var hostingEnvironment = new AspNetCoreHostingEnvironment ( hostingSettings , webHostEnvironment ,
httpContextAccessor , hostApplicationLifetime ) ;
2020-03-13 10:00:03 +01:00
var ioHelper = new IOHelper ( hostingEnvironment , globalSettings ) ;
2020-03-18 19:17:51 +01:00
var logger = SerilogLogger . CreateWithDefaultConfiguration ( hostingEnvironment ,
new AspNetCoreSessionIdResolver ( httpContextAccessor ) ,
( ) = > services . BuildServiceProvider ( ) . GetService < IRequestCache > ( ) , coreDebug , ioHelper ,
new AspNetCoreMarchal ( ) ) ;
2020-03-12 16:56:39 +01:00
2020-03-13 10:00:03 +01:00
var backOfficeInfo = new AspNetCoreBackOfficeInfo ( globalSettings ) ;
2020-02-24 16:18:47 +01:00
var profiler = new LogProfiler ( logger ) ;
2020-02-25 08:56:58 +01:00
Current . Initialize ( logger , configs , ioHelper , hostingEnvironment , backOfficeInfo , profiler ) ;
2020-03-16 14:02:08 +01:00
return services ;
2020-02-24 16:18:47 +01:00
}
2020-03-23 15:50:01 +11:00
2020-02-24 16:18:47 +01:00
private static void CreateCompositionRoot ( IServiceCollection services )
{
2020-03-13 19:10:21 +11:00
// TODO: This isn't the best to have to resolve the services now but to avoid this will
// require quite a lot of re-work.
2020-02-24 16:18:47 +01:00
var serviceProvider = services . BuildServiceProvider ( ) ;
2020-03-13 19:10:21 +11:00
var httpContextAccessor = serviceProvider . GetRequiredService < IHttpContextAccessor > ( ) ;
var webHostEnvironment = serviceProvider . GetRequiredService < IWebHostEnvironment > ( ) ;
var hostApplicationLifetime = serviceProvider . GetRequiredService < IHostApplicationLifetime > ( ) ;
2020-02-24 16:18:47 +01:00
2020-03-23 15:50:01 +11:00
var configs = serviceProvider . GetService < Configs > ( ) ;
2020-02-24 16:18:47 +01:00
2020-03-23 15:50:01 +11:00
var hostingSettings = configs . Hosting ( ) ;
var coreDebug = configs . CoreDebug ( ) ;
var globalSettings = configs . Global ( ) ;
2020-02-24 16:18:47 +01:00
2020-02-27 11:48:38 +01:00
var hostingEnvironment = new AspNetCoreHostingEnvironment ( hostingSettings , webHostEnvironment , httpContextAccessor , hostApplicationLifetime ) ;
2020-03-23 15:50:01 +11:00
var ioHelper = new IOHelper ( hostingEnvironment , globalSettings ) ;
var logger = SerilogLogger . CreateWithDefaultConfiguration ( hostingEnvironment ,
new AspNetCoreSessionIdResolver ( httpContextAccessor ) ,
( ) = > serviceProvider . GetService < IRequestCache > ( ) , coreDebug , ioHelper ,
new AspNetCoreMarchal ( ) ) ;
2020-03-12 16:56:39 +01:00
2020-02-24 16:18:47 +01:00
var backOfficeInfo = new AspNetCoreBackOfficeInfo ( configs . Global ( ) ) ;
var profiler = new LogProfiler ( logger ) ;
2020-02-25 08:56:58 +01:00
Current . Initialize ( logger , configs , ioHelper , hostingEnvironment , backOfficeInfo , profiler ) ;
2020-02-24 16:18:47 +01:00
}
2020-03-13 18:44:58 +11:00
private class AspNetCoreBootPermissionsChecker : IUmbracoBootPermissionChecker
{
public void ThrowIfNotPermissions ( )
{
// nothing to check
}
}
2020-02-18 08:32:06 +01:00
}
}