From daf972fc62d7153ec0af26b24d52264d6eae74c3 Mon Sep 17 00:00:00 2001 From: Paul Johnson Date: Thu, 19 Nov 2020 20:47:41 +0000 Subject: [PATCH] Closer to removing all BuildServiceProvider calls --- .../Composing/TypeFinderConfig.cs | 4 +- src/Umbraco.Core/StaticApplicationLogging.cs | 13 +- .../UmbracoBuilderExtensions.cs | 4 +- .../Testing/UmbracoIntegrationTest.cs | 10 +- .../UmbracoCoreServiceCollectionExtensions.cs | 113 +++++++++--------- 5 files changed, 65 insertions(+), 79 deletions(-) diff --git a/src/Umbraco.Core/Composing/TypeFinderConfig.cs b/src/Umbraco.Core/Composing/TypeFinderConfig.cs index 302d45b4e8..ef862fd49d 100644 --- a/src/Umbraco.Core/Composing/TypeFinderConfig.cs +++ b/src/Umbraco.Core/Composing/TypeFinderConfig.cs @@ -15,9 +15,9 @@ namespace Umbraco.Core.Composing private readonly TypeFinderSettings _settings; private IEnumerable _assembliesAcceptingLoadExceptions; - public TypeFinderConfig(IOptionsMonitor settings) + public TypeFinderConfig(IOptions settings) { - _settings = settings.CurrentValue; + _settings = settings.Value; } public IEnumerable AssembliesAcceptingLoadExceptions diff --git a/src/Umbraco.Core/StaticApplicationLogging.cs b/src/Umbraco.Core/StaticApplicationLogging.cs index 73db382812..84cdc3c2d2 100644 --- a/src/Umbraco.Core/StaticApplicationLogging.cs +++ b/src/Umbraco.Core/StaticApplicationLogging.cs @@ -1,5 +1,3 @@ -using System; -using System.Diagnostics; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -18,16 +16,7 @@ namespace Umbraco.Core public static ILogger CreateLogger() { - try - { - return _loggerFactory?.CreateLogger() ?? NullLoggerFactory.Instance.CreateLogger(); - } - catch (ObjectDisposedException) - { - // TODO: Weird, investigate, ScopedRepositoryTests.FullDataSetRepositoryCachePolicy etc - Debugger.Break(); - return NullLoggerFactory.Instance.CreateLogger(); - } + return _loggerFactory?.CreateLogger() ?? NullLoggerFactory.Instance.CreateLogger(); } } } diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs index 30f44443a1..c797d5f37b 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs @@ -26,7 +26,7 @@ namespace Umbraco.Tests.Integration.TestServerTest testHelper.GetLoggingConfiguration(), builder.Config, // TODO: Yep that's extremely ugly - (lambdaBuilder, globalSettings, connectionStrings, umbVersion, ioHelper, loggerFactory, profiler, hostingEnv, backOfficeInfo, typeFinder, appCaches, dbProviderFactoryCreator) => + (lambdaBuilder, globalSettings, connectionStrings, umbVersion, ioHelper, profiler, hostingEnv, typeFinder, appCaches, dbProviderFactoryCreator) => { UmbracoIntegrationTest.ConfigureSomeMorebitsForTests( lambdaBuilder, @@ -34,10 +34,8 @@ namespace Umbraco.Tests.Integration.TestServerTest connectionStrings, umbVersion, ioHelper, - loggerFactory, profiler, hostingEnv, - backOfficeInfo, typeFinder, appCaches, dbProviderFactoryCreator, diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs index 8747fde7b7..07217caccb 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -185,10 +185,8 @@ namespace Umbraco.Tests.Integration.Testing ConnectionStrings connectionStrings, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, - ILoggerFactory loggerFactory, IProfiler profiler, Core.Hosting.IHostingEnvironment hostingEnvironment, - IBackOfficeInfo backOfficeInfo, ITypeFinder typeFinder, AppCaches appCaches, IDbProviderFactoryCreator dbProviderFactoryCreator) @@ -199,10 +197,8 @@ namespace Umbraco.Tests.Integration.Testing connectionStrings, umbracoVersion, ioHelper, - loggerFactory, profiler, hostingEnvironment, - backOfficeInfo, typeFinder, appCaches, dbProviderFactoryCreator, @@ -234,10 +230,8 @@ namespace Umbraco.Tests.Integration.Testing ConnectionStrings connectionStrings, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, - ILoggerFactory loggerFactory, IProfiler profiler, Core.Hosting.IHostingEnvironment hostingEnvironment, - IBackOfficeInfo backOfficeInfo, ITypeFinder typeFinder, AppCaches appCaches, IDbProviderFactoryCreator dbProviderFactoryCreator, @@ -262,7 +256,6 @@ namespace Umbraco.Tests.Integration.Testing builder.Services.AddUnique(umbracoVersion); builder.Services.AddUnique(dbProviderFactoryCreator); builder.Services.AddUnique(hostingEnvironment); - builder.Services.AddUnique(backOfficeInfo); builder.Services.AddUnique(); // after bootstrapping we let the container wire up for us. @@ -341,6 +334,7 @@ namespace Umbraco.Tests.Integration.Testing protected void TerminateCoreRuntime() { Services.GetRequiredService().Terminate(); + StaticApplicationLogging.Initialize(null); } #endregion @@ -352,7 +346,7 @@ namespace Umbraco.Tests.Integration.Testing protected void UseTestLocalDb(IServiceProvider serviceProvider) { - var state = serviceProvider.GetRequiredService() as RuntimeState; + var state = serviceProvider.GetRequiredService(); var databaseFactory = serviceProvider.GetRequiredService(); // This will create a db, install the schema and ensure the app is configured to run diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs index 33fab47715..66bcdaa6fb 100644 --- a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Data.Common; using System.Data.SqlClient; using System.IO; @@ -36,21 +37,18 @@ namespace Umbraco.Extensions { public static class UmbracoCoreServiceCollectionExtensions { - - /// /// Adds the Umbraco Back Core requirements /// - /// + /// /// - /// /// - /// - /// + /// /// - /// Delegate to create an - /// + /// + /// Weird hack for tests, won't exist much longer /// + /// Shouldn't exist public static IUmbracoBuilder AddUmbracoCore( this IUmbracoBuilder builder, IWebHostEnvironment webHostEnvironment, @@ -59,7 +57,7 @@ namespace Umbraco.Extensions ILoggingConfiguration loggingConfiguration, IConfiguration configuration, //TODO: Yep that's extremely ugly - Action configureSomeMoreBits) + Action configureSomeMoreBits) { if (builder is null) throw new ArgumentNullException(nameof(builder)); if (entryAssembly is null) throw new ArgumentNullException(nameof(entryAssembly)); @@ -74,55 +72,49 @@ namespace Umbraco.Extensions options.Cookie.Name = "UMB_SESSION"; options.Cookie.HttpOnly = true; }); + var syntaxProviders = new List(); + var insertProviders = new List(); + var databaseCreators = new List(); // Add supported databases - builder.Services.AddUmbracoSqlCeSupport(); - builder.Services.AddUmbracoSqlServerSupport(); + builder.Services.AddUmbracoSqlCeSupport(syntaxProviders, insertProviders, databaseCreators); + builder.Services.AddUmbracoSqlServerSupport(syntaxProviders, insertProviders, databaseCreators); - builder.Services.AddSingleton(x => new DbProviderFactoryCreator( + var dbProviderFactoryCreator = new DbProviderFactoryCreator( DbProviderFactories.GetFactory, - x.GetServices(), - x.GetServices(), - x.GetServices() - )); + syntaxProviders, + insertProviders, + databaseCreators); - // TODO: We want to avoid pre-resolving a container as much as possible we should not - // be doing this any more than we are now. The ugly part about this is that the service - // instances resolved here won't be the same instances resolved from the container - // later once the true container is built. However! ... in the case of IDbProviderFactoryCreator - // it will be the same instance resolved later because we are re-registering this instance back - // into the container. This is not true for `Configs` but we should do that too, see comments in - // `RegisterEssentials`. + builder.Services.AddSingleton(dbProviderFactoryCreator); + + // TODO: We should not be doing this at all. var serviceProvider = builder.Services.BuildServiceProvider(); - var globalSettings = serviceProvider.GetService>(); - var connectionStrings = serviceProvider.GetService>(); - var hostingSettings = serviceProvider.GetService>(); - var typeFinderSettings = serviceProvider.GetService>(); - - var dbProviderFactoryCreator = serviceProvider.GetRequiredService(); - + // Switching to IOptions vs IOptionsMonitor was rejected previously as it prevents setting IsDebug true without a restart + var hostingSettings = serviceProvider.GetService>(); // <--- We are now building ServiceProvider just for this line var hostingEnvironment = new AspNetCoreHostingEnvironment(hostingSettings, webHostEnvironment); var ioHelper = new IOHelper(hostingEnvironment); - var backOfficeInfo = new AspNetCoreBackOfficeInfo(globalSettings); var profiler = GetWebProfiler(hostingEnvironment); + builder.Services.AddUnique(); + builder.Services.AddLogger(loggingConfiguration, configuration); var loggerFactory = builder.BuilderLoggerFactory; - var umbracoVersion = new UmbracoVersion(); - var typeFinder = CreateTypeFinder(loggerFactory, profiler, webHostEnvironment, entryAssembly, typeFinderSettings); + var typeFinderSettings = builder.Config.GetSection(Core.Constants.Configuration.ConfigTypeFinder).Get() ?? new TypeFinderSettings(); + var typeFinder = CreateTypeFinder(loggerFactory, profiler, webHostEnvironment, entryAssembly, Options.Create(typeFinderSettings)); + var globalSettings = builder.Config.GetSection(Core.Constants.Configuration.ConfigGlobal).Get() ?? new GlobalSettings(); + var connectionStrings = builder.Config.GetSection("ConnectionStrings").Get(opt => opt.BindNonPublicProperties = true) ?? new ConnectionStrings(); configureSomeMoreBits( builder, - globalSettings.CurrentValue, - connectionStrings.Value, - umbracoVersion, + globalSettings, + connectionStrings, + new UmbracoVersion(), ioHelper, - loggerFactory, profiler, hostingEnvironment, - backOfficeInfo, typeFinder, appCaches, dbProviderFactoryCreator); @@ -144,9 +136,11 @@ namespace Umbraco.Extensions /// /// Adds SqlCe support for Umbraco /// - /// - /// - private static IServiceCollection AddUmbracoSqlCeSupport(this IServiceCollection services) + private static IServiceCollection AddUmbracoSqlCeSupport( + this IServiceCollection services, + ICollection syntaxProviders, + ICollection insertProviders, + ICollection databaseCreators) { try { @@ -165,6 +159,10 @@ namespace Umbraco.Extensions services.AddSingleton(typeof(ISqlSyntaxProvider), sqlCeSyntaxProviderType); services.AddSingleton(typeof(IBulkSqlInsertProvider), sqlCeBulkSqlInsertProviderType); services.AddSingleton(typeof(IEmbeddedDatabaseCreator), sqlCeEmbeddedDatabaseCreatorType); + + syntaxProviders.Add((ISqlSyntaxProvider)Activator.CreateInstance(sqlCeSyntaxProviderType)); + insertProviders.Add((IBulkSqlInsertProvider)Activator.CreateInstance(sqlCeBulkSqlInsertProviderType)); + databaseCreators.Add((IEmbeddedDatabaseCreator)Activator.CreateInstance(sqlCeEmbeddedDatabaseCreatorType)); } var sqlCeAssembly = Assembly.LoadFrom(Path.Combine(binFolder, "System.Data.SqlServerCe.dll")); @@ -187,15 +185,25 @@ namespace Umbraco.Extensions /// /// Adds Sql Server support for Umbraco /// - /// - /// - public static IServiceCollection AddUmbracoSqlServerSupport(this IServiceCollection services) + public static IServiceCollection AddUmbracoSqlServerSupport( + this IServiceCollection services, + ICollection syntaxProviders, + ICollection insertProviders, + ICollection databaseCreators) { DbProviderFactories.RegisterFactory(Core.Constants.DbProviderNames.SqlServer, SqlClientFactory.Instance); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + var syntaxProvider = new SqlServerSyntaxProvider(); + var insertProvider = new SqlServerBulkSqlInsertProvider(); + var databaseCreator = new NoopEmbeddedDatabaseCreator(); + + services.AddSingleton(syntaxProvider); + services.AddSingleton(insertProvider); + services.AddSingleton(databaseCreator); + + syntaxProviders.Add(syntaxProvider); + insertProviders.Add(insertProvider); + databaseCreators.Add(databaseCreator); return services; } @@ -230,7 +238,7 @@ namespace Umbraco.Extensions return services; } - private static ITypeFinder CreateTypeFinder(ILoggerFactory loggerFactory, IProfiler profiler, IWebHostEnvironment webHostEnvironment, Assembly entryAssembly, IOptionsMonitor typeFinderSettings) + private static ITypeFinder CreateTypeFinder(ILoggerFactory loggerFactory, IProfiler profiler, IWebHostEnvironment webHostEnvironment, Assembly entryAssembly, IOptions typeFinderSettings) { var runtimeHashPaths = new RuntimeHashPaths(); runtimeHashPaths.AddFolder(new DirectoryInfo(Path.Combine(webHostEnvironment.ContentRootPath, "bin"))); @@ -244,10 +252,8 @@ namespace Umbraco.Extensions ConnectionStrings connectionStrings, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, - ILoggerFactory loggerFactory, IProfiler profiler, IHostingEnvironment hostingEnvironment, - IBackOfficeInfo backOfficeInfo, ITypeFinder typeFinder, AppCaches appCaches, IDbProviderFactoryCreator dbProviderFactoryCreator) @@ -257,10 +263,10 @@ namespace Umbraco.Extensions var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); var mainDomLock = appSettingMainDomLock == "SqlMainDomLock" || isWindows == false - ? (IMainDomLock)new SqlMainDomLock(loggerFactory.CreateLogger(), loggerFactory, globalSettings, connectionStrings, dbProviderFactoryCreator, hostingEnvironment) - : new MainDomSemaphoreLock(loggerFactory.CreateLogger(), hostingEnvironment); + ? (IMainDomLock)new SqlMainDomLock(builder.BuilderLoggerFactory.CreateLogger(), builder.BuilderLoggerFactory, globalSettings, connectionStrings, dbProviderFactoryCreator, hostingEnvironment) + : new MainDomSemaphoreLock(builder.BuilderLoggerFactory.CreateLogger(), hostingEnvironment); - var mainDom = new MainDom(loggerFactory.CreateLogger(), mainDomLock); + var mainDom = new MainDom(builder.BuilderLoggerFactory.CreateLogger(), mainDomLock); var logger = builder.BuilderLoggerFactory.CreateLogger(); @@ -297,7 +303,6 @@ namespace Umbraco.Extensions builder.Services.AddUnique(umbracoVersion); builder.Services.AddUnique(dbProviderFactoryCreator); builder.Services.AddUnique(hostingEnvironment); - builder.Services.AddUnique(backOfficeInfo); builder.Services.AddUnique(); // after bootstrapping we let the container wire up for us.