From ec66990e72aef5b5d46421409f59fc3a30dc1058 Mon Sep 17 00:00:00 2001 From: Paul Johnson Date: Tue, 27 Oct 2020 10:53:01 +0000 Subject: [PATCH] NetCore: MSDI refactor phase 2 (#9280) * Moved adapters from Infra -> Core * Allow Composition to accept a service collection instead of an IRegister * Composition no longer takes IRegister as constructor arg all tests passing * Composition no longer implements IRegister * Lose _uniques in Composition * lose Composition OnCreatingFactory actions * Clean up UmbracoCoreServiceCollectionExtensions & Composition Less IFactory * LightInject gone where TFW == netstandard2.0 || TFW == netcoreapp3.1 * Resolve dead code issues * Rename IFactory methods to match IServiceProvider so they can be trivially swapped later. * Rename IFactory methods to match IServiceProvider so they can be trivially swapped later (continued) Thought the counts were low, it's mostly extension method usage --- .../Composing/CollectionBuilderBase.cs | 2 +- .../Composing/ComponentCollectionBuilder.cs | 2 +- src/Umbraco.Core/Composing/Composition.cs | 69 +--- src/Umbraco.Core/Composing/IFactory.cs | 8 +- .../ServiceCollectionRegistryAdapter.cs | 33 +- .../ServiceProviderFactoryAdapter.cs | 49 +++ .../CompositionExtensions_Uniques.cs | 4 +- .../ContentAppFactoryCollectionBuilder.cs | 8 +- .../Dashboards/DashboardCollectionBuilder.cs | 2 +- src/Umbraco.Core/FactoryExtensions.cs | 10 +- .../Sections/SectionCollectionBuilder.cs | 2 +- src/Umbraco.Core/Services/IRuntime.cs | 10 +- ...aseServerRegistrarAndMessengerComponent.cs | 4 +- .../CoreMappingProfiles.cs | 7 +- .../CompositionExtensions/FileSystems.cs | 12 +- .../CompositionExtensions/Installer.cs | 25 +- .../CompositionExtensions/Services.cs | 34 +- .../LightInject/LightInjectContainer.cs | 250 ----------- .../LightInject/LightInjectException.cs | 112 ----- .../MixedLightInjectScopeManagerProvider.cs | 43 -- .../Composing/RegisterFactory.cs | 65 --- .../ServiceProviderFactoryAdapter.cs | 49 --- .../CompositionExtensions_Essentials.cs | 4 +- .../Logging/Viewer/LogViewerComposer.cs | 6 +- .../Mappers/MapperCollectionBuilder.cs | 2 +- .../Runtime/CoreInitialComposer.cs | 45 +- .../Runtime/CoreRuntime.cs | 72 ++-- .../Search/ExamineComposer.cs | 33 +- .../Umbraco.Infrastructure.csproj | 5 - .../Compose/ModelsBuilderComposer.cs | 11 +- .../NuCacheComposer.cs | 9 +- src/Umbraco.Tests.Common/Assertions.cs | 35 -- .../Composing/LightInjectValidation.cs | 319 --------------- .../Composing/ValidationResultExtensions.cs | 107 ----- src/Umbraco.Tests.Common/TestHelperBase.cs | 4 +- .../Testing/UmbracoTestAttribute.cs | 2 +- src/Umbraco.Tests.Integration/RuntimeTests.cs | 9 +- .../UmbracoBuilderExtensions.cs | 5 +- .../Testing/IntegrationTestComposer.cs | 6 +- .../Testing/UmbracoIntegrationTest.cs | 4 +- .../Repositories/RelationRepositoryTest.cs | 4 +- .../Services/ContentServiceTests.cs | 4 + .../Umbraco.Tests.Integration.csproj | 1 - .../TestHelpers/BaseUsingSqlSyntax.cs | 7 +- .../TestHelpers/CompositionExtenions.cs | 18 + .../TestHelpers/TestHelper.cs | 3 +- .../Umbraco.Core/Components/ComponentTests.cs | 30 +- .../Composing/CollectionBuildersTests.cs | 31 +- .../Composing/ContainerConformingTests.cs | 387 ------------------ .../Composing/LazyCollectionBuilderTests.cs | 22 +- .../Composing/PackageActionCollectionTests.cs | 5 +- .../PublishedContentCacheTests.cs | 4 +- .../PublishedMediaCacheTests.cs | 8 +- src/Umbraco.Tests/IO/FileSystemsTests.cs | 32 +- src/Umbraco.Tests/Issues/U9560.cs | 4 +- src/Umbraco.Tests/Models/ContentXmlTest.cs | 2 +- src/Umbraco.Tests/Models/MediaXmlTest.cs | 2 +- .../Packaging/PackageDataInstallationTests.cs | 4 +- .../Packaging/PackageInstallationTest.cs | 8 +- .../Published/ConvertersTests.cs | 18 +- .../PublishedContent/NuCacheChildrenTests.cs | 4 +- .../PublishedContent/NuCacheTests.cs | 4 +- .../PublishedContentSnapshotTestBase.cs | 2 +- .../PublishedContentTestBase.cs | 2 +- .../PublishedContent/PublishedContentTests.cs | 8 +- .../PublishedContent/PublishedMediaTests.cs | 34 +- .../Routing/BaseUrlProviderTest.cs | 3 +- .../Routing/ContentFinderByIdTests.cs | 2 +- .../Routing/DomainsAndCulturesTests.cs | 5 +- .../Routing/RenderRouteHandlerTests.cs | 10 +- .../Routing/UrlsProviderWithDomainsTests.cs | 3 +- .../Routing/UrlsWithNestedDomains.cs | 3 +- .../Runtimes/CoreRuntimeTests.cs | 45 +- .../Scoping/ScopeEventDispatcherTests.cs | 10 +- .../Scoping/ScopedNuCacheTests.cs | 4 +- src/Umbraco.Tests/Scoping/ScopedXmlTests.cs | 2 +- .../TestHelpers/BaseUsingSqlCeSyntax.cs | 10 +- src/Umbraco.Tests/TestHelpers/BaseWebTest.cs | 10 +- .../Stubs/TestControllerFactory.cs | 2 +- .../TestHelpers/TestObjects-Mocks.cs | 2 +- src/Umbraco.Tests/TestHelpers/TestObjects.cs | 6 +- .../TestHelpers/TestWithDatabaseBase.cs | 31 +- .../Testing/TestingTests/MockTests.cs | 3 +- src/Umbraco.Tests/Testing/UmbracoTestBase.cs | 69 ++-- src/Umbraco.Tests/UmbracoExamine/IndexTest.cs | 12 +- .../UmbracoExamine/SearchTests.cs | 2 +- src/Umbraco.Tests/Web/UmbracoHelperTests.cs | 2 +- .../Extensions/WebMappingProfiles.cs | 5 +- .../Runtime/BackOfficeComposer.cs | 11 +- .../Builder/UmbracoBuilderExtensions.cs | 2 +- .../ApplicationBuilderExtensions.cs | 6 +- .../UmbracoCoreServiceCollectionExtensions.cs | 27 +- .../Runtime/AspNetCoreComposer.cs | 3 +- .../RuntimeMinification/SmidgeComposer.cs | 5 +- .../Views/Partials/Grid/Editors/Rte.cshtml | 6 +- src/Umbraco.Web/Composing/Current.cs | 96 ++--- src/Umbraco.Web/Composing/ModuleInjector.cs | 4 +- src/Umbraco.Web/CompositionExtensions.cs | 33 +- .../EnsurePublishedContentRequestAttribute.cs | 4 +- src/Umbraco.Web/Mvc/PluginController.cs | 10 +- src/Umbraco.Web/Mvc/RenderRouteHandler.cs | 2 +- .../Mvc/UmbracoViewPageOfTModel.cs | 8 +- .../Mvc/UmbracoVirtualNodeRouteHandler.cs | 2 +- src/Umbraco.Web/PublishedContentExtensions.cs | 4 +- src/Umbraco.Web/Runtime/WebInitialComposer.cs | 26 +- src/Umbraco.Web/Umbraco.Web.csproj | 2 +- src/Umbraco.Web/UmbracoApplicationBase.cs | 14 +- src/Umbraco.Web/UmbracoDefaultOwinStartup.cs | 6 +- .../Filters/FeatureAuthorizeAttribute.cs | 2 +- .../WebApi/HttpActionContextExtensions.cs | 2 +- .../WebApi/UmbracoApiControllerBase.cs | 18 +- 111 files changed, 662 insertions(+), 1998 deletions(-) rename src/{Umbraco.Infrastructure => Umbraco.Core}/Composing/ServiceCollectionRegistryAdapter.cs (66%) create mode 100644 src/Umbraco.Core/Composing/ServiceProviderFactoryAdapter.cs delete mode 100644 src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs delete mode 100644 src/Umbraco.Infrastructure/Composing/LightInject/LightInjectException.cs delete mode 100644 src/Umbraco.Infrastructure/Composing/LightInject/MixedLightInjectScopeManagerProvider.cs delete mode 100644 src/Umbraco.Infrastructure/Composing/RegisterFactory.cs delete mode 100644 src/Umbraco.Infrastructure/Composing/ServiceProviderFactoryAdapter.cs delete mode 100644 src/Umbraco.Tests.Common/Assertions.cs delete mode 100644 src/Umbraco.Tests.Common/Composing/LightInjectValidation.cs delete mode 100644 src/Umbraco.Tests.Common/Composing/ValidationResultExtensions.cs create mode 100644 src/Umbraco.Tests.UnitTests/TestHelpers/CompositionExtenions.cs delete mode 100644 src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ContainerConformingTests.cs diff --git a/src/Umbraco.Core/Composing/CollectionBuilderBase.cs b/src/Umbraco.Core/Composing/CollectionBuilderBase.cs index ca2bac3905..2b47ba2a86 100644 --- a/src/Umbraco.Core/Composing/CollectionBuilderBase.cs +++ b/src/Umbraco.Core/Composing/CollectionBuilderBase.cs @@ -108,7 +108,7 @@ namespace Umbraco.Core.Composing /// Creates a collection item. /// protected virtual TItem CreateItem(IFactory factory, Type itemType) - => (TItem) factory.GetInstance(itemType); + => (TItem) factory.GetRequiredService(itemType); /// /// Creates a collection. diff --git a/src/Umbraco.Core/Composing/ComponentCollectionBuilder.cs b/src/Umbraco.Core/Composing/ComponentCollectionBuilder.cs index 47968d3568..05e627b41e 100644 --- a/src/Umbraco.Core/Composing/ComponentCollectionBuilder.cs +++ b/src/Umbraco.Core/Composing/ComponentCollectionBuilder.cs @@ -20,7 +20,7 @@ namespace Umbraco.Core.Composing protected override IEnumerable CreateItems(IFactory factory) { - _logger = factory.GetInstance(); + _logger = factory.GetRequiredService(); using (_logger.DebugDuration($"Creating components. (log when >{LogThresholdMilliseconds}ms)", "Created.")) { diff --git a/src/Umbraco.Core/Composing/Composition.cs b/src/Umbraco.Core/Composing/Composition.cs index 4ebc8c8f7e..66e6e03e8e 100644 --- a/src/Umbraco.Core/Composing/Composition.cs +++ b/src/Umbraco.Core/Composing/Composition.cs @@ -1,9 +1,14 @@ using System; using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Core.Logging; +using Umbraco.Infrastructure.Composing; + +using NoFactory = Umbraco.Infrastructure.Composing.ServiceProviderFactoryAdapter; namespace Umbraco.Core.Composing { @@ -15,25 +20,14 @@ namespace Umbraco.Core.Composing /// avoid accessing the container. This is because everything needs to be properly registered and with /// the proper lifecycle. These methods will take care of it. Directly registering into the container /// may cause issues. - public class Composition : IRegister + public class Composition { private readonly Dictionary _builders = new Dictionary(); - private readonly Dictionary> _uniques = new Dictionary>(); - private readonly IRegister _register; + private IRegister _register => ServiceCollectionRegistryAdapter.Wrap(Services); - /// - /// Initializes a new instance of the class. - /// - /// A register. - /// A type loader. - /// A logger. - /// The runtime state. - /// Optional configs. - /// An IOHelper - /// - public Composition(IRegister register, TypeLoader typeLoader, IProfilingLogger logger, IRuntimeState runtimeState, IIOHelper ioHelper, AppCaches appCaches) + public Composition(IServiceCollection services, TypeLoader typeLoader, IProfilingLogger logger, IRuntimeState runtimeState, IIOHelper ioHelper, AppCaches appCaches) { - _register = register ?? throw new ArgumentNullException(nameof(register)); + Services = services ?? throw new ArgumentNullException(nameof(services)); TypeLoader = typeLoader ?? throw new ArgumentNullException(nameof(typeLoader)); Logger = logger ?? throw new ArgumentNullException(nameof(logger)); RuntimeState = runtimeState ?? throw new ArgumentNullException(nameof(runtimeState)); @@ -51,6 +45,8 @@ namespace Umbraco.Core.Composing public IIOHelper IOHelper { get; } public AppCaches AppCaches { get; } + public IServiceCollection Services { get; } + /// /// Gets the type loader. /// @@ -84,56 +80,23 @@ namespace Umbraco.Core.Composing /// - public IFactory CreateFactory() + public void RegisterBuilders() { - foreach (var onCreating in OnCreatingFactory.Values) - onCreating(); - - foreach (var unique in _uniques.Values) - unique(_register); - _uniques.Clear(); // no point keep them around - foreach (var builder in _builders.Values) builder.RegisterWith(_register); _builders.Clear(); // no point keep them around - - return _register.CreateFactory(); } - /// - /// Gets a dictionary of action to execute when creating the factory. - /// - public Dictionary OnCreatingFactory { get; } = new Dictionary(); - #endregion #region Unique - - private string GetUniqueName() - => GetUniqueName(typeof(TService)); - - private string GetUniqueName(Type serviceType) - => serviceType.FullName; - - private string GetUniqueName() - => GetUniqueName(typeof(TService), typeof(TTarget)); - - private string GetUniqueName(Type serviceType, Type targetType) - => serviceType.FullName + "::" + targetType.FullName; - - /// - /// Registers a unique service as its own implementation. - /// - /// Unique services have one single implementation, and a Singleton lifetime. - public void RegisterUnique(Type serviceType) - => _uniques[GetUniqueName(serviceType)] = register => register.Register(serviceType, Lifetime.Singleton); - + /// /// Registers a unique service with an implementation type. /// /// Unique services have one single implementation, and a Singleton lifetime. public void RegisterUnique(Type serviceType, Type implementingType) - => _uniques[GetUniqueName(serviceType)] = register => register.Register(serviceType, implementingType, Lifetime.Singleton); + => Services.Replace(ServiceDescriptor.Singleton(serviceType, implementingType)); /// /// Registers a unique service with an implementation factory. @@ -141,14 +104,14 @@ namespace Umbraco.Core.Composing /// Unique services have one single implementation, and a Singleton lifetime. public void RegisterUnique(Func factory) where TService : class - => _uniques[GetUniqueName()] = register => register.Register(factory, Lifetime.Singleton); + => Services.Replace(ServiceDescriptor.Singleton(sp => factory(NoFactory.Wrap(sp)))); /// /// Registers a unique service with an implementing instance. /// /// Unique services have one single implementation, and a Singleton lifetime. public void RegisterUnique(Type serviceType, object instance) - => _uniques[GetUniqueName(serviceType)] = register => register.Register(serviceType, instance); + => Services.Replace(ServiceDescriptor.Singleton(serviceType, instance)); #endregion diff --git a/src/Umbraco.Core/Composing/IFactory.cs b/src/Umbraco.Core/Composing/IFactory.cs index c53e523967..7a2af7756e 100644 --- a/src/Umbraco.Core/Composing/IFactory.cs +++ b/src/Umbraco.Core/Composing/IFactory.cs @@ -19,7 +19,7 @@ namespace Umbraco.Core.Composing /// The type of the service. /// An instance of the specified type. /// Throws an exception if the container failed to get an instance of the specified type. - object GetInstance(Type type); + object GetRequiredService(Type type); /// /// Tries to get an instance of a service. @@ -29,19 +29,19 @@ namespace Umbraco.Core.Composing /// Returns null if the container does not know how to get an instance /// of the specified type. Throws an exception if the container does know how /// to get an instance of the specified type, but failed to do so. - object TryGetInstance(Type type); + object GetService(Type type); /// /// Gets all instances of a service. /// /// The type of the service. - IEnumerable GetAllInstances(Type serviceType); + IEnumerable GetServices(Type serviceType); /// /// Gets all instances of a service. /// /// The type of the service. - IEnumerable GetAllInstances() + IEnumerable GetServices() where TService : class; /// diff --git a/src/Umbraco.Infrastructure/Composing/ServiceCollectionRegistryAdapter.cs b/src/Umbraco.Core/Composing/ServiceCollectionRegistryAdapter.cs similarity index 66% rename from src/Umbraco.Infrastructure/Composing/ServiceCollectionRegistryAdapter.cs rename to src/Umbraco.Core/Composing/ServiceCollectionRegistryAdapter.cs index d0ff384cb1..7058ba1e5d 100644 --- a/src/Umbraco.Infrastructure/Composing/ServiceCollectionRegistryAdapter.cs +++ b/src/Umbraco.Core/Composing/ServiceCollectionRegistryAdapter.cs @@ -6,12 +6,12 @@ namespace Umbraco.Infrastructure.Composing { public class ServiceCollectionRegistryAdapter : IRegister { - private readonly IServiceCollection _services; + public IServiceCollection Services { get; } public ServiceCollectionRegistryAdapter(IServiceCollection services) { - _services = services ?? throw new ArgumentNullException(nameof(services)); - _services.AddTransient(typeof(Lazy<>), typeof(LazyResolve<>)); + Services = services ?? throw new ArgumentNullException(nameof(services)); + Services.AddTransient(typeof(Lazy<>), typeof(LazyResolve<>)); } public void Register(Type serviceType, Lifetime lifetime = Lifetime.Transient) @@ -20,13 +20,13 @@ namespace Umbraco.Infrastructure.Composing { case Lifetime.Request: case Lifetime.Scope: - _services.AddScoped(serviceType); + Services.AddScoped(serviceType); break; case Lifetime.Transient: - _services.AddTransient(serviceType); + Services.AddTransient(serviceType); break; case Lifetime.Singleton: - _services.AddSingleton(serviceType); + Services.AddSingleton(serviceType); break; default: throw new NotImplementedException($"Unhandled Lifetime: {lifetime}"); @@ -39,13 +39,13 @@ namespace Umbraco.Infrastructure.Composing { case Lifetime.Request: case Lifetime.Scope: - _services.AddScoped(serviceType, implementingType); + Services.AddScoped(serviceType, implementingType); break; case Lifetime.Transient: - _services.AddTransient(serviceType, implementingType); + Services.AddTransient(serviceType, implementingType); break; case Lifetime.Singleton: - _services.AddSingleton(serviceType, implementingType); + Services.AddSingleton(serviceType, implementingType); break; default: throw new NotImplementedException($"Unhandled Lifetime: {lifetime}"); @@ -58,13 +58,13 @@ namespace Umbraco.Infrastructure.Composing { case Lifetime.Request: case Lifetime.Scope: - _services.AddScoped(sp => factory(ServiceProviderFactoryAdapter.Wrap(sp))); + Services.AddScoped(sp => factory(ServiceProviderFactoryAdapter.Wrap(sp))); break; case Lifetime.Transient: - _services.AddTransient(sp => factory(ServiceProviderFactoryAdapter.Wrap(sp))); + Services.AddTransient(sp => factory(ServiceProviderFactoryAdapter.Wrap(sp))); break; case Lifetime.Singleton: - _services.AddSingleton(sp => factory(ServiceProviderFactoryAdapter.Wrap(sp))); + Services.AddSingleton(sp => factory(ServiceProviderFactoryAdapter.Wrap(sp))); break; default: throw new NotImplementedException($"Unhandled Lifetime: {lifetime}"); @@ -72,12 +72,17 @@ namespace Umbraco.Infrastructure.Composing } public void Register(Type serviceType, object instance) { - _services.AddSingleton(serviceType, instance); + Services.AddSingleton(serviceType, instance); } public IFactory CreateFactory() { - return ServiceProviderFactoryAdapter.Wrap(_services.BuildServiceProvider()); + return ServiceProviderFactoryAdapter.Wrap(Services.BuildServiceProvider()); + } + + public static IRegister Wrap(IServiceCollection services) + { + return new ServiceCollectionRegistryAdapter(services); } } diff --git a/src/Umbraco.Core/Composing/ServiceProviderFactoryAdapter.cs b/src/Umbraco.Core/Composing/ServiceProviderFactoryAdapter.cs new file mode 100644 index 0000000000..eb53880ee2 --- /dev/null +++ b/src/Umbraco.Core/Composing/ServiceProviderFactoryAdapter.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Core.Composing; + +namespace Umbraco.Infrastructure.Composing +{ + public class ServiceProviderFactoryAdapter : IFactory + { + public IServiceProvider ServiceProvider { get; } + + private ServiceProviderFactoryAdapter(IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + } + + public object Concrete => ServiceProvider; + + public object GetRequiredService(Type type) + { + return ServiceProvider.GetRequiredService(type); + } + + public object GetService(Type type) + { + return ServiceProvider.GetService(type); + } + + public IEnumerable GetServices(Type serviceType) + { + return ServiceProvider.GetServices(serviceType); + } + + public IEnumerable GetServices() where TService : class + { + return ServiceProvider.GetServices(); + } + + public IDisposable BeginScope() + { + return ServiceProvider.CreateScope(); + } + + public static IFactory Wrap(IServiceProvider serviceProvider) + { + return new ServiceProviderFactoryAdapter(serviceProvider); + } + } +} diff --git a/src/Umbraco.Core/CompositionExtensions_Uniques.cs b/src/Umbraco.Core/CompositionExtensions_Uniques.cs index cc08889c2d..11d4877aca 100644 --- a/src/Umbraco.Core/CompositionExtensions_Uniques.cs +++ b/src/Umbraco.Core/CompositionExtensions_Uniques.cs @@ -36,8 +36,8 @@ namespace Umbraco.Core where TService2 : class { composition.RegisterUnique(); - composition.RegisterUnique(factory => factory.GetInstance()); - composition.RegisterUnique(factory => factory.GetInstance()); + composition.RegisterUnique(factory => factory.GetRequiredService()); + composition.RegisterUnique(factory => factory.GetRequiredService()); } } } diff --git a/src/Umbraco.Core/ContentApps/ContentAppFactoryCollectionBuilder.cs b/src/Umbraco.Core/ContentApps/ContentAppFactoryCollectionBuilder.cs index 0e2c8e2f55..4e1c7d8693 100644 --- a/src/Umbraco.Core/ContentApps/ContentAppFactoryCollectionBuilder.cs +++ b/src/Umbraco.Core/ContentApps/ContentAppFactoryCollectionBuilder.cs @@ -18,8 +18,8 @@ namespace Umbraco.Web.ContentApps public override ContentAppFactoryCollection CreateCollection(IFactory factory) { // get the logger factory just-in-time - see note below for manifest parser - var loggerFactory = factory.GetInstance(); - var umbracoContextAccessor = factory.GetInstance(); + var loggerFactory = factory.GetRequiredService(); + var umbracoContextAccessor = factory.GetRequiredService(); return new ContentAppFactoryCollection(CreateItems(factory), loggerFactory.CreateLogger(), umbracoContextAccessor); } @@ -28,8 +28,8 @@ namespace Umbraco.Web.ContentApps // get the manifest parser just-in-time - injecting it in the ctor would mean that // simply getting the builder in order to configure the collection, would require // its dependencies too, and that can create cycles or other oddities - var manifestParser = factory.GetInstance(); - var ioHelper = factory.GetInstance(); + var manifestParser = factory.GetRequiredService(); + var ioHelper = factory.GetRequiredService(); return base.CreateItems(factory).Concat(manifestParser.Manifest.ContentApps.Select(x => new ManifestContentAppFactory(x, ioHelper))); } } diff --git a/src/Umbraco.Core/Dashboards/DashboardCollectionBuilder.cs b/src/Umbraco.Core/Dashboards/DashboardCollectionBuilder.cs index a903d15abb..8bad0cb23c 100644 --- a/src/Umbraco.Core/Dashboards/DashboardCollectionBuilder.cs +++ b/src/Umbraco.Core/Dashboards/DashboardCollectionBuilder.cs @@ -31,7 +31,7 @@ namespace Umbraco.Web.Dashboards // get the manifest parser just-in-time - injecting it in the ctor would mean that // simply getting the builder in order to configure the collection, would require // its dependencies too, and that can create cycles or other oddities - var manifestParser = factory.GetInstance(); + var manifestParser = factory.GetRequiredService(); var dashboardSections = Merge(base.CreateItems(factory), manifestParser.Manifest.Dashboards); diff --git a/src/Umbraco.Core/FactoryExtensions.cs b/src/Umbraco.Core/FactoryExtensions.cs index 8ae2f76af3..0a5c04c98f 100644 --- a/src/Umbraco.Core/FactoryExtensions.cs +++ b/src/Umbraco.Core/FactoryExtensions.cs @@ -18,9 +18,9 @@ namespace Umbraco.Core /// The factory. /// An instance of the specified type. /// Throws an exception if the factory failed to get an instance of the specified type. - public static T GetInstance(this IFactory factory) + public static T GetRequiredService(this IFactory factory) where T : class - => (T)factory.GetInstance(typeof(T)); + => (T)factory.GetRequiredService(typeof(T)); /// /// Tries to get an instance of a service. @@ -30,9 +30,9 @@ namespace Umbraco.Core /// Returns null if the factory does not know how to get an instance /// of the specified type. Throws an exception if the factory does know how /// to get an instance of the specified type, but failed to do so. - public static T TryGetInstance(this IFactory factory) + public static T GetService(this IFactory factory) where T : class - => (T)factory.TryGetInstance(typeof(T)); + => (T)factory.GetService(typeof(T)); /// /// Creates an instance with arguments. @@ -96,7 +96,7 @@ namespace Umbraco.Core else { // None of the provided arguments is suitable: get an instance from the factory - ctorArgs[i++] = factory.GetInstance(parameter.ParameterType); + ctorArgs[i++] = factory.GetRequiredService(parameter.ParameterType); } } return ctor.Invoke(ctorArgs); diff --git a/src/Umbraco.Core/Sections/SectionCollectionBuilder.cs b/src/Umbraco.Core/Sections/SectionCollectionBuilder.cs index de883db83a..d122816949 100644 --- a/src/Umbraco.Core/Sections/SectionCollectionBuilder.cs +++ b/src/Umbraco.Core/Sections/SectionCollectionBuilder.cs @@ -16,7 +16,7 @@ namespace Umbraco.Web.Sections // get the manifest parser just-in-time - injecting it in the ctor would mean that // simply getting the builder in order to configure the collection, would require // its dependencies too, and that can create cycles or other oddities - var manifestParser = factory.GetInstance(); + var manifestParser = factory.GetRequiredService(); return base.CreateItems(factory).Concat(manifestParser.Manifest.Sections); } diff --git a/src/Umbraco.Core/Services/IRuntime.cs b/src/Umbraco.Core/Services/IRuntime.cs index 4715068073..ff533be76e 100644 --- a/src/Umbraco.Core/Services/IRuntime.cs +++ b/src/Umbraco.Core/Services/IRuntime.cs @@ -1,4 +1,6 @@ -using Umbraco.Core.Composing; +using System; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Core.Composing; using Umbraco.Core.Configuration; namespace Umbraco.Core @@ -11,16 +13,14 @@ namespace Umbraco.Core /// /// Boots the runtime. /// - /// The application register. - /// The application factory. - IFactory Configure(IRegister register); + void Configure(IServiceCollection services); /// /// Gets the runtime state. /// IRuntimeState State { get; } - void Start(); + void Start(IServiceProvider serviceProvider); /// /// Terminates the runtime. diff --git a/src/Umbraco.Infrastructure/Compose/DatabaseServerRegistrarAndMessengerComponent.cs b/src/Umbraco.Infrastructure/Compose/DatabaseServerRegistrarAndMessengerComponent.cs index 096c5d5686..420730d779 100644 --- a/src/Umbraco.Infrastructure/Compose/DatabaseServerRegistrarAndMessengerComponent.cs +++ b/src/Umbraco.Infrastructure/Compose/DatabaseServerRegistrarAndMessengerComponent.cs @@ -46,7 +46,7 @@ namespace Umbraco.Web.Compose //rebuild the xml cache file if the server is not synced () => { - var publishedSnapshotService = factory.GetInstance(); + var publishedSnapshotService = factory.GetRequiredService(); // rebuild the published snapshot caches entirely, if the server is not synced // this is equivalent to DistributedCache RefreshAll... but local only @@ -62,7 +62,7 @@ namespace Umbraco.Web.Compose // indexes then they can adjust this logic themselves. () => { - var indexRebuilder = factory.GetInstance(); + var indexRebuilder = factory.GetRequiredService(); indexRebuilder.RebuildIndexes(false, 5000); } } diff --git a/src/Umbraco.Infrastructure/Composing/CompositionExtensions/CoreMappingProfiles.cs b/src/Umbraco.Infrastructure/Composing/CompositionExtensions/CoreMappingProfiles.cs index 057dad0da6..fc2f8c9e88 100644 --- a/src/Umbraco.Infrastructure/Composing/CompositionExtensions/CoreMappingProfiles.cs +++ b/src/Umbraco.Infrastructure/Composing/CompositionExtensions/CoreMappingProfiles.cs @@ -1,4 +1,5 @@ -using Umbraco.Core.BackOffice; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Core.BackOffice; using Umbraco.Core.Mapping; using Umbraco.Web.Models.Mapping; @@ -36,8 +37,8 @@ namespace Umbraco.Core.Composing.CompositionExtensions .Add() ; - composition.Register(); - composition.Register(); + composition.Services.AddTransient(); + composition.Services.AddTransient(); return composition; } diff --git a/src/Umbraco.Infrastructure/Composing/CompositionExtensions/FileSystems.cs b/src/Umbraco.Infrastructure/Composing/CompositionExtensions/FileSystems.cs index adba706d13..b19558ef44 100644 --- a/src/Umbraco.Infrastructure/Composing/CompositionExtensions/FileSystems.cs +++ b/src/Umbraco.Infrastructure/Composing/CompositionExtensions/FileSystems.cs @@ -39,7 +39,7 @@ namespace Umbraco.Core.Composing.CompositionExtensions composition.RegisterUnique(factory => factory.CreateInstance(factory)); // register IFileSystems, which gives access too all filesystems - composition.RegisterUnique(factory => factory.GetInstance()); + composition.RegisterUnique(factory => factory.GetRequiredService()); // register the scheme for media paths composition.RegisterUnique(); @@ -47,16 +47,16 @@ namespace Umbraco.Core.Composing.CompositionExtensions // register the default IMediaFileSystem implementation composition.RegisterUnique(factory => { - var ioHelper = factory.GetInstance(); - var hostingEnvironment = factory.GetInstance(); - var logger = factory.GetInstance>(); - var globalSettings = factory.GetInstance>().Value; + var ioHelper = factory.GetRequiredService(); + var hostingEnvironment = factory.GetRequiredService(); + var logger = factory.GetRequiredService>(); + var globalSettings = factory.GetRequiredService>().Value; var rootPath = hostingEnvironment.MapPathWebRoot(globalSettings.UmbracoMediaPath); var rootUrl = hostingEnvironment.ToAbsolute(globalSettings.UmbracoMediaPath); var inner = new PhysicalFileSystem(ioHelper, hostingEnvironment, logger, rootPath, rootUrl); - var fileSystems = factory.GetInstance(); + var fileSystems = factory.GetRequiredService(); return fileSystems.GetFileSystem(inner); }); diff --git a/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Installer.cs b/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Installer.cs index d49d1b4783..403e13816e 100644 --- a/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Installer.cs +++ b/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Installer.cs @@ -1,4 +1,5 @@ -using Umbraco.Core; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Web.Install; using Umbraco.Web.Install.InstallSteps; @@ -12,21 +13,21 @@ namespace Umbraco.Web.Composing.CompositionExtensions { // register the installer steps - composition.Register(Lifetime.Scope); - composition.Register(Lifetime.Scope); - composition.Register(Lifetime.Scope); - composition.Register(Lifetime.Scope); - composition.Register(Lifetime.Scope); - composition.Register(Lifetime.Scope); + composition.Services.AddScoped(); + composition.Services.AddScoped(); + composition.Services.AddScoped(); + composition.Services.AddScoped(); + composition.Services.AddScoped(); + composition.Services.AddScoped(); // TODO: Add these back once we have a compatible Starter kit - // composition.Register(Lifetime.Scope); - // composition.Register(Lifetime.Scope); - // composition.Register(Lifetime.Scope); + // composition.Services.AddScoped(); + // composition.Services.AddScoped(); + // composition.Services.AddScoped(); - composition.Register(Lifetime.Scope); + composition.Services.AddScoped(); - composition.Register(); + composition.Services.AddTransient(); composition.RegisterUnique(); return composition; diff --git a/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Services.cs b/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Services.cs index a4744d3d2d..37c0bae384 100644 --- a/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Services.cs +++ b/src/Umbraco.Infrastructure/Composing/CompositionExtensions/Services.cs @@ -60,8 +60,8 @@ namespace Umbraco.Core.Composing.CompositionExtensions composition.RegisterUnique(); composition.Register(SourcesFactory); composition.RegisterUnique(factory => new LocalizedTextService( - factory.GetInstance>(), - factory.GetInstance>())); + factory.GetRequiredService>(), + factory.GetRequiredService>())); composition.RegisterUnique(); @@ -86,23 +86,23 @@ namespace Umbraco.Core.Composing.CompositionExtensions /// private static PackagesRepository CreatePackageRepository(IFactory factory, string packageRepoFileName) => new PackagesRepository( - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance>(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService>(), packageRepoFileName); private static LocalizedTextServiceFileSources SourcesFactory(IFactory container) { - var hostingEnvironment = container.GetInstance(); - var globalSettings = container.GetInstance>().Value; + var hostingEnvironment = container.GetRequiredService(); + var globalSettings = container.GetRequiredService>().Value; var mainLangFolder = new DirectoryInfo(hostingEnvironment.MapPathContentRoot(WebPath.Combine(globalSettings.UmbracoPath , "config","lang"))); var appPlugins = new DirectoryInfo(hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.AppPlugins)); var configLangFolder = new DirectoryInfo(hostingEnvironment.MapPathContentRoot(WebPath.Combine(Constants.SystemDirectories.Config ,"lang"))); @@ -122,8 +122,8 @@ namespace Umbraco.Core.Composing.CompositionExtensions .Select(x => new LocalizedTextServiceSupplementaryFileSource(x, true)); return new LocalizedTextServiceFileSources( - container.GetInstance>(), - container.GetInstance(), + container.GetRequiredService>(), + container.GetRequiredService(), mainLangFolder, pluginLangFolders.Concat(userLangFolders)); } diff --git a/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs b/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs deleted file mode 100644 index 3537230c2b..0000000000 --- a/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectContainer.cs +++ /dev/null @@ -1,250 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Threading; -using LightInject; - -namespace Umbraco.Core.Composing.LightInject -{ - /// - /// Implements DI with LightInject. - /// - public class LightInjectContainer : IRegister, IFactory, IDisposable - { - private int _disposed; - - /// - /// Initializes a new instance of the with a LightInject container. - /// - public LightInjectContainer(ServiceContainer container) - { - Container = ConfigureContainer(container); - } - - //TODO: The Create methods can die when net framework is gone - - /// - /// Creates a new instance of the class. - /// - public static LightInjectContainer Create() - => new LightInjectContainer(CreateServiceContainer()); - - /// - /// Creates a new instance of the LightInject service container. - /// - protected static ServiceContainer CreateServiceContainer() - { - var container = new ServiceContainer(new ContainerOptions { EnablePropertyInjection = false }); - ConfigureContainer(container); - return container; - } - - private static ServiceContainer ConfigureContainer(ServiceContainer container) - { - // note: the block below is disabled, as it is too LightInject-specific - // - // supports annotated constructor injections - // eg to specify the service name on some services - //container.EnableAnnotatedConstructorInjection(); - - // note: the block below is disabled, we do not allow property injection at all anymore - // (see options in CreateServiceContainer) - // - // from the docs: "LightInject considers all read/write properties a dependency, but implements - // a loose strategy around property dependencies, meaning that it will NOT throw an exception - // in the case of an unresolved property dependency." - // - // in Umbraco we do NOT want to do property injection by default, so we have to disable it. - // from the docs, the following line will cause the container to "now only try to inject - // dependencies for properties that is annotated with the InjectAttribute." - // - // could not find it documented, but tests & code review shows that LightInject considers a - // property to be "injectable" when its setter exists and is not static, nor private, nor - // it is an index property. which means that eg protected or internal setters are OK. - //Container.EnableAnnotatedPropertyInjection(); - - // ensure that we do *not* scan assemblies - // we explicitly RegisterFrom our own composition roots and don't want them scanned - container.AssemblyScanner = new AssemblyScanner(/*container.AssemblyScanner*/); - - // see notes in MixedLightInjectScopeManagerProvider - container.ScopeManagerProvider = new MixedLightInjectScopeManagerProvider(); - - // note: the block below is disabled, because it does not work, because collection builders - // are singletons, and constructor dependencies don't work on singletons, see - // https://github.com/seesharper/LightInject/issues/294 - // - // if looking for a IContainer, and one was passed in args, use it - // this is for collection builders which require the IContainer - //container.RegisterConstructorDependency((c, i, a) => a.OfType().FirstOrDefault()); - // - // and, the block below is also disabled, because it is ugly - // - //// which means that the only way to inject the container into builders is to register it - //container.RegisterInstance(this); - // - // instead, we use an explicit GetInstance with arguments implementation - - return container; - } - - /// - /// Gets the LightInject container. - /// - public ServiceContainer Container { get; } - - /// - /// - public object Concrete => Container; - - /// - public void Dispose() - { - if (Interlocked.Exchange(ref _disposed, 1) == 1) - return; - - Container.Dispose(); - } - - /// - public IFactory CreateFactory() => this; - - private static string GetTargetedServiceName() => "TARGET:" + typeof(TTarget).FullName; - - #region Factory - - /// - public object GetInstance(Type type) - => Container.GetInstance(type); - - /// - public TService GetInstanceFor() - => Container.GetInstance(GetTargetedServiceName()); - - /// - public object TryGetInstance(Type type) - => Container.TryGetInstance(type); - - /// - public IEnumerable GetAllInstances() - where T : class - => Container.GetAllInstances(); - - /// - public IEnumerable GetAllInstances(Type type) - => Container.GetAllInstances(type); - - /// - public void Release(object instance) - { - // nothing to release with LightInject - } - - // notes: - // we may want to look into MS code, eg: - // TypeActivatorCache in MVC at https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/Internal/TypeActivatorCache.cs - // which relies onto - // ActivatorUtilities at https://github.com/aspnet/DependencyInjection/blob/master/shared/Microsoft.Extensions.ActivatorUtilities.Sources/ActivatorUtilities.cs - - #endregion - - #region Registry - - /// - public void Register(Type serviceType, Lifetime lifetime = Lifetime.Transient) - => Container.Register(serviceType, GetLifetime(lifetime)); - - /// - public void Register(Type serviceType, Type implementingType, Lifetime lifetime = Lifetime.Transient) - { - switch (lifetime) - { - case Lifetime.Transient: - Container.Register(serviceType, implementingType, implementingType.Name); - break; - case Lifetime.Request: - case Lifetime.Scope: - case Lifetime.Singleton: - Container.Register(serviceType, implementingType, GetLifetime(lifetime)); - break; - default: - throw new NotSupportedException($"Lifetime {lifetime} is not supported."); - } - } - - /// - public void Register(Func factory, Lifetime lifetime = Lifetime.Transient) - where TService : class - { - Container.Register(f => factory(this), GetLifetime(lifetime)); - } - - /// - public void Register(Type serviceType, object instance) - => Container.RegisterInstance(serviceType, instance); - - private ILifetime GetLifetime(Lifetime lifetime) - { - switch (lifetime) - { - case Lifetime.Transient: - return null; - case Lifetime.Request: - return new PerRequestLifeTime(); - case Lifetime.Scope: - return new PerScopeLifetime(); - case Lifetime.Singleton: - return new PerContainerLifetime(); - default: - throw new NotSupportedException($"Lifetime {lifetime} is not supported."); - } - } - - /// - public void RegisterAuto(Type serviceBaseType) - { - Container.RegisterFallback((serviceType, serviceName) => - { - // https://github.com/seesharper/LightInject/issues/173 - if (serviceBaseType.IsAssignableFromGtd(serviceType)) - Container.Register(serviceType); - return false; - }, null); - } - - #endregion - - #region Control - - /// - public IDisposable BeginScope() - => Container.BeginScope(); - - /// - public virtual void ConfigureForWeb() - { } - - /// - public virtual void EnablePerWebRequestScope() - { - if (!(Container.ScopeManagerProvider is MixedLightInjectScopeManagerProvider smp)) - throw new Exception("Container.ScopeManagerProvider is not MixedLightInjectScopeManagerProvider."); - smp.EnablePerWebRequestScope(new PerLogicalCallContextScopeManagerProvider()); - } - - private class AssemblyScanner : IAssemblyScanner - { - public void Scan(Assembly assembly, IServiceRegistry serviceRegistry, Func lifetime, Func shouldRegister, Func serviceNameProvider) - { - // nothing - we don't want LightInject to scan - } - - public void Scan(Assembly assembly, IServiceRegistry serviceRegistry) - { - // nothing - we don't want LightInject to scan - } - } - - #endregion - } -} diff --git a/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectException.cs b/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectException.cs deleted file mode 100644 index e1344468f9..0000000000 --- a/src/Umbraco.Infrastructure/Composing/LightInject/LightInjectException.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Runtime.Serialization; -using System.Text; - -namespace Umbraco.Core.Composing.LightInject -{ - /// - /// Represents errors that occur due to LightInject. - /// - /// - [Serializable] - public class LightInjectException : Exception - { - private const string LightInjectUnableToResolveType = "Unable to resolve type:"; - private const string LightInjectUnresolvedDependency = "Unresolved dependency "; - private const string LightInjectRequestedDependency = "[Requested dependency:"; - - /// - /// Initializes a new instance of the class. - /// - public LightInjectException() - { } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - public LightInjectException(string message) - : base(message) - { } - - /// - /// Initializes a new instance of the class. - /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception, or a null reference ( in Visual Basic) if no inner exception is specified. - public LightInjectException(string message, Exception innerException) - : base(message, innerException) - { } - - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - protected LightInjectException(SerializationInfo info, StreamingContext context) - : base(info, context) - { } - - /// - /// Tries to throw the exception with additional details. - /// - /// The exception. - /// - public static void TryThrow(Exception e) - { - var ex = e as InvalidOperationException; - if (ex == null || ex.Message.StartsWith(LightInjectUnableToResolveType) == false) - return; - - var sb = new StringBuilder(); - sb.AppendLine("Unresolved type: " + ex.Message.Substring(LightInjectUnableToResolveType.Length)); - WriteDetails(ex, sb); - throw new LightInjectException(sb.ToString(), e); - } - - /// - /// Tries to throw the exception with additional details. - /// - /// The exception. - /// The implementing type. - /// - public static void TryThrow(Exception e, Type implementingType) - { - var ex = e as InvalidOperationException; - if (ex == null || ex.Message.StartsWith(LightInjectUnableToResolveType) == false) - return; - - var sb = new StringBuilder(); - sb.AppendLine("Unresolved type: " + ex.Message.Substring(LightInjectUnableToResolveType.Length)); - sb.AppendLine("Implementing type: " + implementingType); - WriteDetails(ex, sb); - throw new LightInjectException(sb.ToString(), e); - } - - /// - /// Writes the details. - /// - /// The exception. - /// The to write the details to. - private static void WriteDetails(InvalidOperationException ex, StringBuilder sb) - { - ex = ex.InnerException as InvalidOperationException; - while (ex != null) - { - var message = ex.Message; - - if (message.StartsWith(LightInjectUnableToResolveType)) - { - sb.AppendLine("-> Unresolved type: " + message.Substring(LightInjectUnableToResolveType.Length)); - } - else if (message.StartsWith(LightInjectUnresolvedDependency)) - { - var pos = message.InvariantIndexOf(LightInjectRequestedDependency); - sb.AppendLine("-> Unresolved dependency: " + message.Substring(pos + LightInjectRequestedDependency.Length + 1).TrimEnd(']')); - } - - ex = ex.InnerException as InvalidOperationException; - } - } - } -} diff --git a/src/Umbraco.Infrastructure/Composing/LightInject/MixedLightInjectScopeManagerProvider.cs b/src/Umbraco.Infrastructure/Composing/LightInject/MixedLightInjectScopeManagerProvider.cs deleted file mode 100644 index 3175376b33..0000000000 --- a/src/Umbraco.Infrastructure/Composing/LightInject/MixedLightInjectScopeManagerProvider.cs +++ /dev/null @@ -1,43 +0,0 @@ -using LightInject; - -namespace Umbraco.Core.Composing.LightInject -{ - // by default, the container's scope manager provider is PerThreadScopeManagerProvider, - // and then container.EnablePerWebRequestScope() replaces it with PerWebRequestScopeManagerProvider, - // however if any delegate has been compiled already at that point, it captures the scope - // manager provider and changing it afterwards has no effect for that delegate. - // - // therefore, Umbraco uses the mixed scope manager provider, which initially wraps an instance - // of PerThreadScopeManagerProvider and then can replace that wrapped instance with an instance - // of PerWebRequestScopeManagerProvider - but all delegates see is the mixed one - and therefore - // they can transition without issues. - // - // The PerWebRequestScopeManager maintains the scope in HttpContext and LightInject registers a - // module (PreApplicationStartMethod) which disposes it on EndRequest - // - // the mixed provider is installed in container.ConfigureUmbracoCore() and then, - // when doing eg container.EnableMvc() or anything that does container.EnablePerWebRequestScope() - // we need to take great care to preserve the mixed scope manager provider! - - public class MixedLightInjectScopeManagerProvider : IScopeManagerProvider - { - private IScopeManagerProvider _provider; - - public MixedLightInjectScopeManagerProvider() - { - _provider = new PerThreadScopeManagerProvider(); - } - - public void EnablePerWebRequestScope(IScopeManagerProvider perRequestScopeProvider) - { - if (perRequestScopeProvider.GetType().IsAssignableFrom(_provider.GetType())) return; - _provider = perRequestScopeProvider; - } - - public IScopeManager GetScopeManager(IServiceFactory factory) - { - return _provider.GetScopeManager(factory); - } - } -} - diff --git a/src/Umbraco.Infrastructure/Composing/RegisterFactory.cs b/src/Umbraco.Infrastructure/Composing/RegisterFactory.cs deleted file mode 100644 index e065852538..0000000000 --- a/src/Umbraco.Infrastructure/Composing/RegisterFactory.cs +++ /dev/null @@ -1,65 +0,0 @@ -using LightInject; -using LightInject.Microsoft.DependencyInjection; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using System; -using System.Reflection; -using Umbraco.Core.Composing.LightInject; -using Umbraco.Core.Configuration; -using Umbraco.Core.Configuration.Models; - -namespace Umbraco.Core.Composing -{ - - /// - /// Creates the container. - /// - public static class RegisterFactory - { - //TODO: This can die when net framework is gone - - // cannot use typeof().AssemblyQualifiedName on the web container - we don't reference it - // a normal Umbraco site should run on the web container, but an app may run on the core one - private const string CoreLightInjectContainerTypeName = "Umbraco.Core.Composing.LightInject.LightInjectContainer,Umbraco.Core"; - private const string WebLightInjectContainerTypeName = "Umbraco.Core.Composing.LightInject.LightInjectContainer,Umbraco.Infrastructure"; - - /// - /// Creates a new instance of the configured container. - /// - /// - /// To override the default LightInjectContainer, add an appSetting named 'Umbraco.Core.RegisterType' with - /// a fully qualified type name to a class with a static method "Create" returning an IRegister. - /// - public static IRegister Create(GlobalSettings globalSettings) - { - Type type; - - var configuredTypeName = globalSettings.RegisterType; - if (configuredTypeName.IsNullOrWhiteSpace()) - { - // try to get the web LightInject container type, - // else the core LightInject container type - type = Type.GetType(configuredTypeName = WebLightInjectContainerTypeName) ?? - Type.GetType(configuredTypeName = CoreLightInjectContainerTypeName); - } - else - { - // try to get the configured type - type = Type.GetType(configuredTypeName); - } - - if (type == null) - throw new Exception($"Cannot find register factory class '{configuredTypeName}'."); - - var factoryMethod = type.GetMethod("Create", BindingFlags.Public | BindingFlags.Static); - if (factoryMethod == null) - throw new Exception($"Register factory class '{configuredTypeName}' does not have a public static method named Create."); - - var container = factoryMethod.Invoke(null, Array.Empty()) as IRegister; - if (container == null) - throw new Exception($"Register factory '{configuredTypeName}' did not return an IRegister implementation."); - - return container; - } - } -} diff --git a/src/Umbraco.Infrastructure/Composing/ServiceProviderFactoryAdapter.cs b/src/Umbraco.Infrastructure/Composing/ServiceProviderFactoryAdapter.cs deleted file mode 100644 index 1273e40123..0000000000 --- a/src/Umbraco.Infrastructure/Composing/ServiceProviderFactoryAdapter.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.Extensions.DependencyInjection; -using Umbraco.Core.Composing; - -namespace Umbraco.Infrastructure.Composing -{ - internal class ServiceProviderFactoryAdapter : IFactory - { - private readonly IServiceProvider _serviceProvider; - - private ServiceProviderFactoryAdapter(IServiceProvider serviceProvider) - { - _serviceProvider = serviceProvider; - } - - public object Concrete => _serviceProvider; - - public object GetInstance(Type type) - { - return _serviceProvider.GetRequiredService(type); - } - - public object TryGetInstance(Type type) - { - return _serviceProvider.GetService(type); - } - - public IEnumerable GetAllInstances(Type serviceType) - { - return _serviceProvider.GetServices(serviceType); - } - - public IEnumerable GetAllInstances() where TService : class - { - return _serviceProvider.GetServices(); - } - - public IDisposable BeginScope() - { - return _serviceProvider.CreateScope(); - } - - public static IFactory Wrap(IServiceProvider serviceProvider) - { - return new ServiceProviderFactoryAdapter(serviceProvider); - } - } -} diff --git a/src/Umbraco.Infrastructure/CompositionExtensions_Essentials.cs b/src/Umbraco.Infrastructure/CompositionExtensions_Essentials.cs index a7e7981daf..630d0970bd 100644 --- a/src/Umbraco.Infrastructure/CompositionExtensions_Essentials.cs +++ b/src/Umbraco.Infrastructure/CompositionExtensions_Essentials.cs @@ -46,14 +46,14 @@ namespace Umbraco.Core composition.RegisterUnique(appCaches); composition.RegisterUnique(appCaches.RequestCache); composition.RegisterUnique(databaseFactory); - composition.RegisterUnique(factory => factory.GetInstance().SqlContext); + composition.RegisterUnique(factory => factory.GetRequiredService().SqlContext); composition.RegisterUnique(typeLoader); composition.RegisterUnique(state); composition.RegisterUnique(typeFinder); composition.RegisterUnique(ioHelper); composition.RegisterUnique(umbracoVersion); composition.RegisterUnique(dbProviderFactoryCreator); - composition.RegisterUnique(factory => factory.GetInstance().BulkSqlInsertProvider); + composition.RegisterUnique(factory => factory.GetRequiredService().BulkSqlInsertProvider); composition.RegisterUnique(hostingEnvironment); composition.RegisterUnique(backOfficeInfo); } diff --git a/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerComposer.cs b/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerComposer.cs index 797e353fcf..2c0f995236 100644 --- a/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerComposer.cs +++ b/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerComposer.cs @@ -17,9 +17,9 @@ namespace Umbraco.Core.Logging.Viewer composition.RegisterUnique(factory => { - return new SerilogJsonLogViewer(factory.GetInstance>(), - factory.GetInstance(), - factory.GetInstance(), + return new SerilogJsonLogViewer(factory.GetRequiredService>(), + factory.GetRequiredService(), + factory.GetRequiredService(), Log.Logger); } ); } diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/MapperCollectionBuilder.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/MapperCollectionBuilder.cs index 66f0c90bfa..77f5b627bb 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/MapperCollectionBuilder.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/MapperCollectionBuilder.cs @@ -20,7 +20,7 @@ namespace Umbraco.Core.Persistence.Mappers // - service IMapperCollection, returns MappersCollectionBuilder's collection register.Register(Lifetime.Singleton); - register.Register(factory => factory.GetInstance()); + register.Register(factory => factory.GetRequiredService()); } public MapperCollectionBuilder AddCoreMappers() diff --git a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs index f9ec706ab7..70e29fd443 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs @@ -1,5 +1,6 @@ using System; using Examine; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Umbraco.Core.Cache; using Umbraco.Core.Composing; @@ -86,8 +87,8 @@ namespace Umbraco.Core.Runtime // register the scope provider composition.RegisterUnique(); // implements both IScopeProvider and IScopeAccessor - composition.RegisterUnique(f => f.GetInstance()); - composition.RegisterUnique(f => f.GetInstance()); + composition.RegisterUnique(f => f.GetRequiredService()); + composition.RegisterUnique(f => f.GetRequiredService()); composition.RegisterUnique(); composition.RegisterUnique(); @@ -95,7 +96,7 @@ namespace Umbraco.Core.Runtime // register database builder // *not* a singleton, don't want to keep it around - composition.Register(); + composition.Services.AddTransient(); // register manifest parser, will be injected in collection builders where needed composition.RegisterUnique(); @@ -130,15 +131,15 @@ namespace Umbraco.Core.Runtime // register a server registrar, by default it's the db registrar composition.RegisterUnique(f => { - var globalSettings = f.GetInstance>().Value; + var globalSettings = f.GetRequiredService>().Value; // TODO: we still register the full IServerMessenger because // even on 1 single server we can have 2 concurrent app domains var singleServer = globalSettings.DisableElectionForSingleServer; return singleServer - ? (IServerRegistrar) new SingleServerRegistrar(f.GetInstance()) + ? (IServerRegistrar) new SingleServerRegistrar(f.GetRequiredService()) : new DatabaseServerRegistrar( - new Lazy(f.GetInstance), + new Lazy(f.GetRequiredService), new DatabaseServerRegistrarOptions()); }); @@ -147,15 +148,15 @@ namespace Umbraco.Core.Runtime // project composition.RegisterUnique(factory => new DatabaseServerMessenger( - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance>(), - factory.GetInstance(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService>(), + factory.GetRequiredService(), true, new DatabaseServerMessengerOptions(), - factory.GetInstance(), - factory.GetInstance() + factory.GetRequiredService(), + factory.GetRequiredService() )); composition.CacheRefreshers() @@ -170,7 +171,7 @@ namespace Umbraco.Core.Runtime composition.RegisterUnique(); composition.RegisterUnique(factory - => new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(factory.GetInstance>().Value))); + => new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(factory.GetRequiredService>().Value))); composition.UrlSegmentProviders() .Append(); @@ -184,7 +185,7 @@ namespace Umbraco.Core.Runtime composition.RegisterUnique(); composition.SetCultureDictionaryFactory(); - composition.Register(f => f.GetInstance().CreateDictionary(), Lifetime.Singleton); + composition.Register(f => f.GetRequiredService().CreateDictionary(), Lifetime.Singleton); composition.RegisterUnique(); // register the published snapshot accessor - the "current" published snapshot is in the umbraco context @@ -318,7 +319,7 @@ namespace Umbraco.Core.Runtime .Append() .Append(); - composition.Register(Lifetime.Request); + composition.Services.AddScoped(); composition.SearchableTrees() .Add(() => composition.TypeLoader.GetTypes()); @@ -333,10 +334,10 @@ namespace Umbraco.Core.Runtime composition.RegisterUnique(); // register distributed cache - composition.RegisterUnique(f => new DistributedCache(f.GetInstance(), f.GetInstance())); + composition.RegisterUnique(f => new DistributedCache(f.GetRequiredService(), f.GetRequiredService())); - composition.Register(Lifetime.Request); + composition.Services.AddScoped(); composition.RegisterUnique(); composition.RegisterUnique(); @@ -346,8 +347,8 @@ namespace Umbraco.Core.Runtime composition.RegisterUnique(); composition.Register(factory => { - var umbCtx = factory.GetInstance(); - return new PublishedContentQuery(umbCtx.UmbracoContext.PublishedSnapshot, factory.GetInstance(), factory.GetInstance()); + var umbCtx = factory.GetRequiredService(); + return new PublishedContentQuery(umbCtx.UmbracoContext.PublishedSnapshot, factory.GetRequiredService(), factory.GetRequiredService()); }, Lifetime.Request); composition.RegisterUnique(); @@ -361,7 +362,7 @@ namespace Umbraco.Core.Runtime // register accessors for cultures composition.RegisterUnique(); - composition.Register(Lifetime.Singleton); + composition.Services.AddSingleton(); composition.RegisterUnique(); diff --git a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs index 56cd2ecbc3..b226169f12 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Umbraco.Core.Cache; @@ -27,13 +28,14 @@ namespace Umbraco.Core.Runtime public class CoreRuntime : IRuntime { private ComponentCollection _components; - private IFactory _factory; // runtime state, this instance will get replaced again once the essential services are available to run the check private RuntimeState _state = RuntimeState.Booting(); private readonly IUmbracoBootPermissionChecker _umbracoBootPermissionChecker; private readonly GlobalSettings _globalSettings; private readonly ConnectionStrings _connectionStrings; + private IServiceProvider _serviceProvider; + public CoreRuntime( GlobalSettings globalSettings, ConnectionStrings connectionStrings, @@ -113,9 +115,9 @@ namespace Umbraco.Core.Runtime public IMainDom MainDom { get; } /// - public virtual IFactory Configure(IRegister register) + public virtual void Configure(IServiceCollection services) { - if (register is null) throw new ArgumentNullException(nameof(register)); + if (services is null) throw new ArgumentNullException(nameof(services)); // create and register the essential services @@ -149,22 +151,19 @@ namespace Umbraco.Core.Runtime // application environment ConfigureUnhandledException(); - _factory = Configure(register, timer); - - return _factory; + Configure(services, timer); } } /// /// Configure the runtime within a timer. /// - private IFactory Configure(IRegister register, DisposableTimer timer) + private void Configure(IServiceCollection services, DisposableTimer timer) { - if (register is null) throw new ArgumentNullException(nameof(register)); + if (services is null) throw new ArgumentNullException(nameof(services)); if (timer is null) throw new ArgumentNullException(nameof(timer)); Composition composition = null; - IFactory factory = null; try { @@ -181,7 +180,7 @@ namespace Umbraco.Core.Runtime _state = new RuntimeState(_globalSettings, UmbracoVersion, databaseFactory, RuntimeLoggerFactory.CreateLogger()); // create the composition - composition = new Composition(register, typeLoader, ProfilingLogger, _state, IOHelper, AppCaches); + composition = new Composition(services, typeLoader, ProfilingLogger, _state, IOHelper, AppCaches); composition.RegisterEssentials(Logger, RuntimeLoggerFactory, Profiler, ProfilingLogger, MainDom, AppCaches, databaseFactory, typeLoader, _state, TypeFinder, IOHelper, UmbracoVersion, DbProviderFactoryCreator, HostingEnvironment, BackOfficeInfo); @@ -202,8 +201,9 @@ namespace Umbraco.Core.Runtime RunComposers(typeLoader, composition); } - // create the factory - factory = composition.CreateFactory(); + composition.RegisterBuilders(); + // TODO: We "should" be able to avoid this + _serviceProvider = composition.Services.BuildServiceProvider(); } catch (Exception e) { @@ -220,14 +220,15 @@ namespace Umbraco.Core.Runtime // if something goes wrong above, we may end up with no factory // meaning nothing can get the runtime state, etc - so let's try // to make sure we have a factory - if (factory == null) + + try { - try - { - factory = composition?.CreateFactory(); - } - catch { /* yea */ } + composition?.RegisterBuilders(); + // TODO: We "should" be able to avoid this + _serviceProvider = composition?.Services.BuildServiceProvider(); } + catch { /* yea */ } + Debugger.Break(); @@ -237,27 +238,30 @@ namespace Umbraco.Core.Runtime // understand this and will nullify themselves, while UmbracoModule will // throw a BootFailedException for every requests. } - - return factory; } - public void Start() + public void Start(IServiceProvider serviceProvider) { + // Capture for CreateDatabaseFactory + // TODO: MSDI - Split core runtime into configure vs startup classes + // TODO: MSDI - Fix CreateDatabaseFactory + _serviceProvider = serviceProvider; + if (_state.Level <= RuntimeLevel.BootFailed) throw new InvalidOperationException($"Cannot start the runtime if the runtime level is less than or equal to {RuntimeLevel.BootFailed}"); // throws if not full-trust _umbracoBootPermissionChecker.ThrowIfNotPermissions(); - var hostingEnvironmentLifetime = _factory.TryGetInstance(); + var hostingEnvironmentLifetime = serviceProvider.GetService(); if (hostingEnvironmentLifetime == null) throw new InvalidOperationException($"An instance of {typeof(IApplicationShutdownRegistry)} could not be resolved from the container, ensure that one if registered in your runtime before calling {nameof(IRuntime)}.{nameof(Start)}"); // acquire the main domain - if this fails then anything that should be registered with MainDom will not operate - AcquireMainDom(MainDom, _factory.GetInstance()); + AcquireMainDom(MainDom, serviceProvider.GetService()); // create & initialize the components - _components = _factory.GetInstance(); + _components = serviceProvider.GetService(); _components.Initialize(); } @@ -356,11 +360,6 @@ namespace Umbraco.Core.Runtime _components?.Terminate(); } - public void ReplaceFactory(IServiceProvider serviceProvider) - { - _factory = ServiceProviderFactoryAdapter.Wrap(serviceProvider); - } - #region Getters // getters can be implemented by runtimes inheriting from CoreRuntime @@ -387,7 +386,20 @@ namespace Umbraco.Core.Runtime /// /// This is strictly internal, for tests only. protected internal virtual IUmbracoDatabaseFactory CreateDatabaseFactory() - => new UmbracoDatabaseFactory(RuntimeLoggerFactory.CreateLogger(), RuntimeLoggerFactory, Options.Create(_globalSettings), Options.Create(_connectionStrings), new Lazy(() => _factory.GetInstance()), DbProviderFactoryCreator); + => new UmbracoDatabaseFactory( + RuntimeLoggerFactory.CreateLogger(), + RuntimeLoggerFactory, + Options.Create(_globalSettings), + Options.Create(_connectionStrings), + new Lazy(() => + { + if (_serviceProvider == null) + { + throw new ApplicationException("_serviceProvider should have been captured from CoreRuntime.Start (or built during configure)"); + } + return _serviceProvider.GetRequiredService(); + }), + DbProviderFactoryCreator); #endregion diff --git a/src/Umbraco.Infrastructure/Search/ExamineComposer.cs b/src/Umbraco.Infrastructure/Search/ExamineComposer.cs index 68a1213629..58de71d920 100644 --- a/src/Umbraco.Infrastructure/Search/ExamineComposer.cs +++ b/src/Umbraco.Infrastructure/Search/ExamineComposer.cs @@ -1,4 +1,5 @@ -using Umbraco.Core; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; @@ -22,29 +23,29 @@ namespace Umbraco.Web.Search // populators are not a collection: one cannot remove ours, and can only add more // the container can inject IEnumerable and get them all - composition.Register(Lifetime.Singleton); - composition.Register(Lifetime.Singleton); - composition.Register(Lifetime.Singleton); - composition.Register(Lifetime.Singleton); + composition.Services.AddSingleton(); + composition.Services.AddSingleton(); + composition.Services.AddSingleton(); + composition.Services.AddSingleton(); - composition.Register(Lifetime.Singleton); + composition.Services.AddSingleton(); composition.RegisterUnique(); composition.RegisterUnique(); composition.RegisterUnique(factory => new ContentValueSetBuilder( - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), true)); composition.RegisterUnique(factory => new ContentValueSetBuilder( - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService(), false)); composition.RegisterUnique, MediaValueSetBuilder>(); composition.RegisterUnique, MemberValueSetBuilder>(); diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj index d8fbbd7fbd..2343ea806a 100644 --- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj +++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj @@ -11,11 +11,6 @@ - - - - - diff --git a/src/Umbraco.ModelsBuilder.Embedded/Compose/ModelsBuilderComposer.cs b/src/Umbraco.ModelsBuilder.Embedded/Compose/ModelsBuilderComposer.cs index bc61f2eaee..f72f3e6de2 100644 --- a/src/Umbraco.ModelsBuilder.Embedded/Compose/ModelsBuilderComposer.cs +++ b/src/Umbraco.ModelsBuilder.Embedded/Compose/ModelsBuilderComposer.cs @@ -1,5 +1,6 @@ using System.Linq; using System.Reflection; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Core.Configuration; using Umbraco.Core; using Umbraco.Core.Logging; @@ -18,7 +19,7 @@ namespace Umbraco.ModelsBuilder.Embedded.Compose public void Compose(Composition composition) { composition.Components().Append(); - composition.Register(Lifetime.Singleton); + composition.Services.AddSingleton(); composition.RegisterUnique(); composition.RegisterUnique(); composition.RegisterUnique(); @@ -27,10 +28,10 @@ namespace Umbraco.ModelsBuilder.Embedded.Compose composition.RegisterUnique(); composition.RegisterUnique(factory => { - var config = factory.GetInstance>().Value; + var config = factory.GetRequiredService>().Value; if (config.ModelsMode == ModelsMode.PureLive) { - return factory.GetInstance(); + return factory.GetRequiredService(); // the following would add @using statement in every view so user's don't // have to do it - however, then noone understands where the @using statement // comes from, and it cannot be avoided / removed --- DISABLED @@ -49,8 +50,8 @@ namespace Umbraco.ModelsBuilder.Embedded.Compose } else if (config.EnableFactory) { - var typeLoader = factory.GetInstance(); - var publishedValueFallback = factory.GetInstance(); + var typeLoader = factory.GetRequiredService(); + var publishedValueFallback = factory.GetRequiredService(); var types = typeLoader .GetTypes() // element models .Concat(typeLoader.GetTypes()); // content models diff --git a/src/Umbraco.PublishedCache.NuCache/NuCacheComposer.cs b/src/Umbraco.PublishedCache.NuCache/NuCacheComposer.cs index d3b1777163..8ebd9d31b9 100644 --- a/src/Umbraco.PublishedCache.NuCache/NuCacheComposer.cs +++ b/src/Umbraco.PublishedCache.NuCache/NuCacheComposer.cs @@ -1,4 +1,5 @@ -using Umbraco.Core; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Models; using Umbraco.Core.Scoping; @@ -15,7 +16,7 @@ namespace Umbraco.Web.PublishedCache.NuCache base.Compose(composition); // register the NuCache database data source - composition.Register(); + composition.Services.AddTransient(); // register the NuCache published snapshot service // must register default options, required in the service ctor @@ -26,8 +27,8 @@ namespace Umbraco.Web.PublishedCache.NuCache // mapping lookups if we are using nucache. composition.RegisterUnique(factory => { - var idkSvc = new IdKeyMap(factory.GetInstance()); - var publishedSnapshotService = factory.GetInstance() as PublishedSnapshotService; + var idkSvc = new IdKeyMap(factory.GetRequiredService()); + var publishedSnapshotService = factory.GetRequiredService() as PublishedSnapshotService; if (publishedSnapshotService != null) { idkSvc.SetMapper(UmbracoObjectTypes.Document, id => publishedSnapshotService.GetDocumentUid(id), uid => publishedSnapshotService.GetDocumentId(uid)); diff --git a/src/Umbraco.Tests.Common/Assertions.cs b/src/Umbraco.Tests.Common/Assertions.cs deleted file mode 100644 index 0f99a6a091..0000000000 --- a/src/Umbraco.Tests.Common/Assertions.cs +++ /dev/null @@ -1,35 +0,0 @@ -using LightInject; -using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Umbraco.Tests.Common.Composing; - -namespace Umbraco.Tests.Common -{ - public class Assertions - { - public static void AssertContainer(ServiceContainer container, bool reportOnly = false) - { - var results = container.Validate().ToList(); - foreach (var resultGroup in results.GroupBy(x => x.Severity).OrderBy(x => x.Key)) - { - Console.WriteLine($"{resultGroup.Key}: {resultGroup.Count()}"); - } - - foreach (var resultGroup in results.GroupBy(x => x.Severity).OrderBy(x => x.Key)) - { - foreach (var result in resultGroup) - { - Console.WriteLine(); - Console.Write(result.ToText()); - } - } - - if (!reportOnly) - Assert.AreEqual(0, results.Count); - } - - } -} diff --git a/src/Umbraco.Tests.Common/Composing/LightInjectValidation.cs b/src/Umbraco.Tests.Common/Composing/LightInjectValidation.cs deleted file mode 100644 index 4925074b9e..0000000000 --- a/src/Umbraco.Tests.Common/Composing/LightInjectValidation.cs +++ /dev/null @@ -1,319 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using LightInject; -using System.Collections.Concurrent; -using System.Collections.ObjectModel; -using System.Reflection; -using ServiceMap = System.Collections.Generic.Dictionary>; - -/********************************************************************************* - The MIT License (MIT) - - Copyright (c) 2017 bernhard.richter@gmail.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -****************************************************************************** - LightInject.Validation version 1.0.1 - http://www.lightinject.net/ - http://twitter.com/bernhardrichter -******************************************************************************/ - -namespace Umbraco.Tests.Common.Composing -{ - public static class LightInjectValidation - { - private static readonly ConcurrentDictionary LifeSpans = new ConcurrentDictionary(); - - private const string NotDisposeMessageServiceType = - @"The service {0} is being injected as a constructor argument into {1} implements IDisposable, " + - "but is registered without a lifetime (transient). LightInject will not be able to dispose the instance represented by {0}. " + - "If the intent was to manually control the instantiation and destruction, inject Func<{0}> instead. " + - "Otherwise register `{0}` with a lifetime (PerContainer, PerRequest or PerScope)."; - - private const string NotDisposeMessageImplementingType = - @"The service {0} represented by {1} is being injected as a constructor argument into {2} implements IDisposable, " + - "but is registered without a lifetime (transient). LightInject will not be able to dispose the instance represented by {0}. " + - "If the intent was to manually control the instantiation and destruction, inject Func<{0}> instead. " + - "Otherwise register `{0}` with a lifetime (PerContainer, PerRequest or PerScope)."; - - - private const string MissingDeferredDependency = - @"The injected '{0}' does not contain a registration for the underlying type '{1}'. " + - "Ensure that '{1}' is registered so that the service can be resolved by '{0}'"; - - /* - The service 'NameSpace.IBar' that is being injected into 'NameSpace.Foo' is registered with -with a 'Transient' lifetime while the 'NameSpace.Foo' is registered with the 'PerScope' lifetime. -Ensure that 'NameSpace.IBar' is registered with a lifetime that is equal to or has a longer lifetime than the 'PerScope' lifetime. - */ - private const string CaptiveDependency = - @"The service '{0}' that is being injected into {1} is registered with " + - "a '{2}' lifetime while the {1} is registered with the '{3}' lifetime. " + - "Ensure that '{0}' is registered with a lifetime that is equal to or has a longer lifetime than the '{3}' lifetime. " + - "Alternatively ensure that `{1}` is registered with a lifetime that is equal to or " + - "has a shorter lifetime than `{2}` lifetime."; - - private const string MissingDependency = - "Class: 'NameSpace.Foo', Parameter 'NameSpace.IBar bar' -> The injected service NameSpace IBar is not registered." - ; - - - static LightInjectValidation() - { - LifeSpans.TryAdd(typeof(PerRequestLifeTime), 10); - LifeSpans.TryAdd(typeof(PerScopeLifetime), 20); - LifeSpans.TryAdd(typeof(PerContainerLifetime), 30); - } - - public static IEnumerable Validate(this ServiceContainer container) - { - var serviceMap = container.AvailableServices.GroupBy(sr => sr.ServiceType).ToDictionary(gr => gr.Key, - gr => gr.ToDictionary(sr => sr.ServiceName, sr => sr, StringComparer.OrdinalIgnoreCase)); - - var verifyableServices = container.AvailableServices.Where(sr => sr.ImplementingType != null); - - return verifyableServices.SelectMany(sr => - ValidateConstructor(serviceMap, sr, container.ConstructorSelector.Execute(sr.ImplementingType))); - } - - private static IReadOnlyCollection ValidateConstructor(ServiceMap serviceMap, - ServiceRegistration serviceRegistration, ConstructorInfo constructorInfo) - { - var result = new Collection(); - - foreach (var parameter in constructorInfo.GetParameters()) - { - var validationTarget = new ValidationTarget(serviceRegistration, parameter); - Validate(validationTarget, serviceMap, result); - } - return result; - } - - private static void Validate(ValidationTarget validationTarget, ServiceMap serviceMap, ICollection result) - { - var registration = GetServiceRegistration(serviceMap, validationTarget); - if (registration == null) - if (validationTarget.ServiceType.IsFunc() || validationTarget.ServiceType.IsLazy()) - { - var serviceType = validationTarget.ServiceType.GenericTypeArguments[0]; - var underlyingvalidationTarget = validationTarget.WithServiceDescription(serviceType, string.Empty); - registration = GetServiceRegistration(serviceMap, underlyingvalidationTarget); - - if (registration != null) - return; - - if (serviceMap.ContainsAmbiguousRegistrationFor(serviceType)) - result.Add(new ValidationResult("", ValidationSeverity.Ambiguous, underlyingvalidationTarget)); - else - { - var message = string.Format(MissingDeferredDependency, validationTarget.ServiceType, underlyingvalidationTarget.ServiceType); - result.Add(new ValidationResult(message, ValidationSeverity.MissingDependency, underlyingvalidationTarget)); - } - } - else if (validationTarget.ServiceType.IsGenericType && validationTarget.ServiceType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) - { - var serviceType = validationTarget.ServiceType.GenericTypeArguments[0]; - var underlyingvalidationTarget = validationTarget.WithServiceDescription(serviceType, string.Empty); - var registrations = GetServiceRegistrations(serviceMap, underlyingvalidationTarget); - if (registrations.Any()) return; - - // strict: there has to be at least 1 - var message = string.Format(MissingDeferredDependency, validationTarget.ServiceType, underlyingvalidationTarget.ServiceType); - result.Add(new ValidationResult(message, ValidationSeverity.MissingDependency, underlyingvalidationTarget)); - } - else - if (serviceMap.ContainsAmbiguousRegistrationFor(validationTarget.ServiceType)) - result.Add(new ValidationResult("", ValidationSeverity.Ambiguous, validationTarget)); - else - result.Add(new ValidationResult("", ValidationSeverity.MissingDependency, validationTarget)); - else - { - ValidateDisposable(validationTarget, result, registration); - ValidateLifetime(validationTarget, registration, result); - } - } - - private static void ValidateDisposable(ValidationTarget validationTarget, ICollection result, - ServiceRegistration registration) - { - if (registration.ServiceType.Implements()) - { - var message = string.Format(NotDisposeMessageServiceType, registration.ServiceType, - validationTarget.DeclaringService.ImplementingType); - result.Add(new ValidationResult(message, ValidationSeverity.NotDisposed, validationTarget)); - } - - else if (registration.ImplementingType != null && registration.ImplementingType.Implements()) - { - var message = string.Format(NotDisposeMessageImplementingType, registration.ImplementingType, - registration.ServiceType, - validationTarget.DeclaringService.ImplementingType); - result.Add(new ValidationResult(message, ValidationSeverity.NotDisposed, validationTarget)); - } - } - - - private static void ValidateLifetime(ValidationTarget validationTarget, ServiceRegistration dependencyRegistration, ICollection result) - { - if (GetLifespan(validationTarget.DeclaringService.Lifetime) > GetLifespan(dependencyRegistration.Lifetime)) - { - var message = string.Format(CaptiveDependency, dependencyRegistration.ServiceType, - validationTarget.DeclaringService.ServiceType, GetLifetimeName(dependencyRegistration.Lifetime), - GetLifetimeName(validationTarget.DeclaringService.Lifetime)); - result.Add(new ValidationResult(message, ValidationSeverity.Captive, validationTarget)); - } - } - - public static void SetLifespan(int lifeSpan) where TLifetime : ILifetime - { - LifeSpans.TryAdd(typeof(TLifetime), lifeSpan); - } - - private static IEnumerable GetServiceRegistrations(ServiceMap serviceMap, ValidationTarget validationTarget) - { - return serviceMap.Where(x => validationTarget.ServiceType.IsAssignableFrom(x.Key)).SelectMany(x => x.Value.Values); - } - - private static ServiceRegistration GetServiceRegistration(ServiceMap serviceMap, ValidationTarget validationTarget) - { - if (!serviceMap.TryGetValue(validationTarget.ServiceType, out var registrations)) - return null; - - if (registrations.TryGetValue(string.Empty, out var registration)) - return registration; - - if (registrations.Count == 1) - return registrations.Values.First(); - - if (registrations.TryGetValue(validationTarget.ServiceName, out registration)) - return registration; - - return null; - } - - private static string GetLifetimeName(ILifetime lifetime) - { - if (lifetime == null) - return "Transient"; - return lifetime.GetType().Name; - } - - private static int GetLifespan(ILifetime lifetime) - { - if (lifetime == null) - return 0; - if (LifeSpans.TryGetValue(lifetime.GetType(), out var lifespan)) - return lifespan; - return 0; - } - } - - - public class ValidationTarget - { - public ServiceRegistration DeclaringService { get; } - public ParameterInfo Parameter { get; } - public Type ServiceType { get; } - public string ServiceName { get; } - - - public ValidationTarget(ServiceRegistration declaringRegistration, ParameterInfo parameter) : this(declaringRegistration, parameter, parameter.ParameterType, string.Empty) - { - } - - - public ValidationTarget(ServiceRegistration declaringService, ParameterInfo parameter, Type serviceType, string serviceName) - { - DeclaringService = declaringService; - Parameter = parameter; - ServiceType = serviceType; - ServiceName = serviceName; - - - if (serviceType.GetTypeInfo().IsGenericType && serviceType.GetTypeInfo().ContainsGenericParameters) - ServiceType = serviceType.GetGenericTypeDefinition(); - - } - - public ValidationTarget WithServiceDescription(Type serviceType, string serviceName) - { - return new ValidationTarget(DeclaringService, Parameter, serviceType, serviceName); - } - - } - - - - - - public class ValidationResult - { - public ValidationResult(string message, ValidationSeverity severity, ValidationTarget validationTarget) - { - Message = message; - Severity = severity; - ValidationTarget = validationTarget; - } - - public string Message { get; } - - public ValidationSeverity Severity { get; } - public ValidationTarget ValidationTarget { get; } - } - - public enum ValidationSeverity - { - NoIssues, - Captive, - NotDisposed, - MissingDependency, - Ambiguous - } - - internal static class TypeExtensions - { - public static bool Implements(this Type type) - { - return type.GetTypeInfo().ImplementedInterfaces.Contains(typeof(TBaseType)); - } - - public static bool IsFunc(this Type type) - { - var typeInfo = type.GetTypeInfo(); - return typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Func<>); - } - - public static bool IsLazy(this Type type) - { - var typeInfo = type.GetTypeInfo(); - return typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Lazy<>); - } - } - - internal static class ServiceMapExtensions - { - public static bool ContainsAmbiguousRegistrationFor(this ServiceMap serviceMap, Type serviceType) - { - if (!serviceMap.TryGetValue(serviceType, out var registrations)) - return false; - return registrations.Count > 1; - } - } -} diff --git a/src/Umbraco.Tests.Common/Composing/ValidationResultExtensions.cs b/src/Umbraco.Tests.Common/Composing/ValidationResultExtensions.cs deleted file mode 100644 index cfd136b63c..0000000000 --- a/src/Umbraco.Tests.Common/Composing/ValidationResultExtensions.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Text; -using Umbraco.Core; - -namespace Umbraco.Tests.Common.Composing -{ - // These are used for Light Inject container validation - public static class ValidationResultExtensions - { - public static string ToText(this ValidationResult result) - { - var text = new StringBuilder(); - - text.AppendLine($"{result.Severity}: {WordWrap(result.Message, 120)}"); - var target = result.ValidationTarget; - text.Append("\tsvce: "); - text.Append(target.ServiceName); - text.Append(target.DeclaringService.ServiceType); - if (!target.DeclaringService.ServiceName.IsNullOrWhiteSpace()) - { - text.Append(" '"); - text.Append(target.DeclaringService.ServiceName); - text.Append("'"); - } - - text.Append(" ("); - if (target.DeclaringService.Lifetime == null) - text.Append("Transient"); - else - text.Append(target.DeclaringService.Lifetime.ToString().TrimStart("LightInject.").TrimEnd("Lifetime")); - text.AppendLine(")"); - text.Append("\timpl: "); - text.Append(target.DeclaringService.ImplementingType); - text.AppendLine(); - text.Append("\tparm: "); - text.Append(target.Parameter); - text.AppendLine(); - - return text.ToString(); - } - - private static string WordWrap(string text, int width) - { - int pos, next; - var sb = new StringBuilder(); - var nl = Environment.NewLine; - - // Lucidity check - if (width < 1) - return text; - - // Parse each line of text - for (pos = 0; pos < text.Length; pos = next) - { - // Find end of line - var eol = text.IndexOf(nl, pos, StringComparison.Ordinal); - - if (eol == -1) - next = eol = text.Length; - else - next = eol + nl.Length; - - // Copy this line of text, breaking into smaller lines as needed - if (eol > pos) - { - do - { - var len = eol - pos; - - if (len > width) - len = BreakLine(text, pos, width); - - if (pos > 0) - sb.Append("\t\t"); - sb.Append(text, pos, len); - sb.Append(nl); - - // Trim whitespace following break - pos += len; - - while (pos < eol && char.IsWhiteSpace(text[pos])) - pos++; - - } while (eol > pos); - } - else sb.Append(nl); // Empty line - } - - return sb.ToString(); - } - - private static int BreakLine(string text, int pos, int max) - { - // Find last whitespace in line - var i = max - 1; - while (i >= 0 && !char.IsWhiteSpace(text[pos + i])) - i--; - if (i < 0) - return max; // No whitespace found; break at maximum length - // Find start of whitespace - while (i >= 0 && char.IsWhiteSpace(text[pos + i])) - i--; - // Return length of text before whitespace - return i + 1; - } - } -} diff --git a/src/Umbraco.Tests.Common/TestHelperBase.cs b/src/Umbraco.Tests.Common/TestHelperBase.cs index 511b100137..0357b7f4ba 100644 --- a/src/Umbraco.Tests.Common/TestHelperBase.cs +++ b/src/Umbraco.Tests.Common/TestHelperBase.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Reflection; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Moq; @@ -19,6 +20,7 @@ using Umbraco.Net; using Umbraco.Core.Persistence; using Umbraco.Core.Serialization; using Umbraco.Core.Strings; +using Umbraco.Infrastructure.Composing; using Umbraco.Web; using Umbraco.Web.Routing; using Umbraco.Tests.Common.Builders; @@ -122,7 +124,7 @@ namespace Umbraco.Tests.Common public IRegister GetRegister() { - return RegisterFactory.Create(new GlobalSettings()); + return ServiceCollectionRegistryAdapter.Wrap(new ServiceCollection()); } public abstract IHostingEnvironment GetHostingEnvironment(); diff --git a/src/Umbraco.Tests.Common/Testing/UmbracoTestAttribute.cs b/src/Umbraco.Tests.Common/Testing/UmbracoTestAttribute.cs index 9248a45d78..f5983ddca6 100644 --- a/src/Umbraco.Tests.Common/Testing/UmbracoTestAttribute.cs +++ b/src/Umbraco.Tests.Common/Testing/UmbracoTestAttribute.cs @@ -62,7 +62,7 @@ namespace Umbraco.Tests.Testing throw new ArgumentException(nameof(other)); base.Merge(other); - + _boot.Set(attr.Boot); _mapper.Set(attr._mapper); _publishedRepositoryEvents.Set(attr._publishedRepositoryEvents); _logger.Set(attr._logger); diff --git a/src/Umbraco.Tests.Integration/RuntimeTests.cs b/src/Umbraco.Tests.Integration/RuntimeTests.cs index edbecad51e..88d000b3a8 100644 --- a/src/Umbraco.Tests.Integration/RuntimeTests.cs +++ b/src/Umbraco.Tests.Integration/RuntimeTests.cs @@ -79,7 +79,7 @@ namespace Umbraco.Tests.Integration testHelper.GetHostingEnvironment(), testHelper.GetBackOfficeInfo(), testHelper.DbProviderFactoryCreator, testHelper.MainDom, testHelper.GetTypeFinder(), AppCaches.NoCache); - coreRuntime.Configure(umbracoContainer); + coreRuntime.Configure(umbracoContainer.Services); Assert.IsTrue(coreRuntime.MainDom.IsMainDom); Assert.IsNull(coreRuntime.State.BootFailedException); @@ -88,8 +88,7 @@ namespace Umbraco.Tests.Integration Assert.IsFalse(MyComponent.IsInit); Assert.IsFalse(MyComponent.IsTerminated); - - coreRuntime.Start(); + coreRuntime.Start(umbracoContainer.Services.BuildServiceProvider()); Assert.IsTrue(MyComponent.IsInit); Assert.IsFalse(MyComponent.IsTerminated); @@ -120,7 +119,7 @@ namespace Umbraco.Tests.Integration // TODO: MSDI - cleanup after initial merge. var register = new ServiceCollectionRegistryAdapter(services); - services.AddUmbracoCore(webHostEnvironment, register, GetType().Assembly, AppCaches.NoCache, testHelper.GetLoggingConfiguration(), hostContext.Configuration,out _); + services.AddUmbracoCore(webHostEnvironment, register, GetType().Assembly, AppCaches.NoCache, testHelper.GetLoggingConfiguration(), hostContext.Configuration); }); var host = await hostBuilder.StartAsync(); @@ -161,7 +160,7 @@ namespace Umbraco.Tests.Integration services.AddUmbracoConfiguration(hostContext.Configuration); // TODO: MSDI - cleanup after initial merge. var register = new ServiceCollectionRegistryAdapter(services); - services.AddUmbracoCore(webHostEnvironment, register, GetType().Assembly, AppCaches.NoCache, testHelper.GetLoggingConfiguration(),hostContext.Configuration, out _); + services.AddUmbracoCore(webHostEnvironment, register, GetType().Assembly, AppCaches.NoCache, testHelper.GetLoggingConfiguration(),hostContext.Configuration); }); var host = await hostBuilder.StartAsync(); diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs index 62585e1423..50918034d5 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs @@ -1,7 +1,5 @@ using System; using Umbraco.Core.Cache; -using Umbraco.Core.Composing.LightInject; -using Umbraco.Core.Configuration.Models; using Umbraco.Core.Runtime; using Umbraco.Extensions; using Umbraco.Infrastructure.Composing; @@ -52,8 +50,7 @@ namespace Umbraco.Tests.Integration.TestServerTest dbInstallEventHandler); // DB Installation event handler return runtime; - }, - out _); + }); }); } } diff --git a/src/Umbraco.Tests.Integration/Testing/IntegrationTestComposer.cs b/src/Umbraco.Tests.Integration/Testing/IntegrationTestComposer.cs index 6e83e57c2c..7e6585c2c2 100644 --- a/src/Umbraco.Tests.Integration/Testing/IntegrationTestComposer.cs +++ b/src/Umbraco.Tests.Integration/Testing/IntegrationTestComposer.cs @@ -68,9 +68,9 @@ namespace Umbraco.Tests.Integration.Testing /// private ILocalizedTextService GetLocalizedTextService(IFactory factory) { - var globalSettings = factory.GetInstance>(); - var loggerFactory = factory.GetInstance(); - var appCaches = factory.GetInstance(); + var globalSettings = factory.GetRequiredService>(); + var loggerFactory = factory.GetRequiredService(); + var appCaches = factory.GetRequiredService(); var localizedTextService = new LocalizedTextService( new Lazy(() => diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs index eed3be9689..f949104ee0 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -6,7 +6,6 @@ using Microsoft.Extensions.Hosting; using NUnit.Framework; using Umbraco.Core.Cache; using Umbraco.Core.Composing; -using Umbraco.Core.Composing.LightInject; using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Core.Logging; @@ -250,8 +249,7 @@ namespace Umbraco.Tests.Integration.Testing AppCaches.NoCache, // Disable caches for integration tests TestHelper.GetLoggingConfiguration(), Configuration, - CreateTestRuntime, - out _); + CreateTestRuntime); services.AddSignalR(); diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationRepositoryTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationRepositoryTest.cs index 1989478186..4d761bdfc1 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationRepositoryTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/RelationRepositoryTest.cs @@ -252,11 +252,11 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Persistence.Repositor [Test] public void Get_Paged_Child_Entities_By_Parent_Id() { - CreateTestDataForPagingTests(out var createdContent, out var createdMembers, out var createdMedia); + CreateTestDataForPagingTests(out var createdContent, out var createdMembers, out _); using (var scope = ScopeProvider.CreateScope()) { - var repository = CreateRepository(ScopeProvider, out var relationTypeRepository); + var repository = CreateRepository(ScopeProvider, out _); // Get parent entities for child id var parents = repository.GetPagedChildEntitiesByParentId(createdContent[0].Id, 0, 6, out var totalRecords).ToList(); diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServiceTests.cs index 36b5e91f34..e4bc6bfc8d 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentServiceTests.cs @@ -443,6 +443,10 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services } [Test] + [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, + PublishedRepositoryEvents = true, + WithApplication = true, + Boot = true)] public void Automatically_Track_Relations() { var mt = MediaTypeBuilder.CreateSimpleMediaType("testMediaType", "Test Media Type"); diff --git a/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj b/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj index 551d714807..f0beaa5828 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj +++ b/src/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj @@ -35,7 +35,6 @@ - diff --git a/src/Umbraco.Tests.UnitTests/TestHelpers/BaseUsingSqlSyntax.cs b/src/Umbraco.Tests.UnitTests/TestHelpers/BaseUsingSqlSyntax.cs index 749354ffde..aa041f7ac8 100644 --- a/src/Umbraco.Tests.UnitTests/TestHelpers/BaseUsingSqlSyntax.cs +++ b/src/Umbraco.Tests.UnitTests/TestHelpers/BaseUsingSqlSyntax.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.SqlSyntax; +using Umbraco.Tests.UnitTests.TestHelpers; namespace Umbraco.Tests.TestHelpers { @@ -27,7 +28,7 @@ namespace Umbraco.Tests.TestHelpers [SetUp] public virtual void Setup() { - var container = TestHelper.GetRegister(); + var container = TestHelper.GetServiceCollection(); var typeLoader = TestHelper.GetMockedTypeLoader(); var composition = new Composition(container, typeLoader, Mock.Of(), Mock.Of(), TestHelper.IOHelper, AppCaches.NoCache); @@ -41,8 +42,8 @@ namespace Umbraco.Tests.TestHelpers var pocoMappers = new NPoco.MapperCollection { new PocoMapper() }; var pocoDataFactory = new FluentPocoDataFactory((type, iPocoDataFactory) => new PocoDataBuilder(type, pocoMappers).Init()); var sqlSyntax = new SqlServerSyntaxProvider(); - SqlContext = new SqlContext(sqlSyntax, DatabaseType.SqlServer2012, pocoDataFactory, new Lazy(() => factory.GetInstance())); - Mappers = factory.GetInstance(); + SqlContext = new SqlContext(sqlSyntax, DatabaseType.SqlServer2012, pocoDataFactory, new Lazy(() => factory.GetRequiredService())); + Mappers = factory.GetRequiredService(); } } } diff --git a/src/Umbraco.Tests.UnitTests/TestHelpers/CompositionExtenions.cs b/src/Umbraco.Tests.UnitTests/TestHelpers/CompositionExtenions.cs new file mode 100644 index 0000000000..cdcc2a88dc --- /dev/null +++ b/src/Umbraco.Tests.UnitTests/TestHelpers/CompositionExtenions.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Core.Composing; +using Umbraco.Infrastructure.Composing; + +namespace Umbraco.Tests.UnitTests.TestHelpers +{ + public static class CompositionExtenions + { + public static IFactory CreateFactory(this Composition composition) + { + composition.RegisterBuilders(); + return ServiceProviderFactoryAdapter.Wrap(composition.Services.BuildServiceProvider()); + } + } +} diff --git a/src/Umbraco.Tests.UnitTests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests.UnitTests/TestHelpers/TestHelper.cs index 81accbf2ba..1ebead07c5 100644 --- a/src/Umbraco.Tests.UnitTests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests.UnitTests/TestHelpers/TestHelper.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Reflection; using System.Threading; using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; using Moq; using NUnit.Framework; using Umbraco.Core; @@ -274,7 +275,7 @@ namespace Umbraco.Tests.TestHelpers public static IUmbracoVersion GetUmbracoVersion() => _testHelperInternal.GetUmbracoVersion(); - public static IRegister GetRegister() => _testHelperInternal.GetRegister(); + public static IServiceCollection GetServiceCollection() => new ServiceCollection(); public static IHostingEnvironment GetHostingEnvironment() => _testHelperInternal.GetHostingEnvironment(); diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Components/ComponentTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Components/ComponentTests.cs index 7b9c043be9..1f6827784f 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Components/ComponentTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Components/ComponentTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -17,6 +18,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Scoping; +using Umbraco.Infrastructure.Composing; using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.UnitTests.Umbraco.Core.Components @@ -45,19 +47,19 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Components var mediaFileSystem = Mock.Of(); var p = new ScopeProvider(f, fs, Options.Create(coreDebug), mediaFileSystem, loggerFactory.CreateLogger(), loggerFactory, typeFinder, NoAppCache.Instance); - mock.Setup(x => x.GetInstance(typeof (ILogger))).Returns(logger); - mock.Setup(x => x.GetInstance(typeof(ILoggerFactory))).Returns(loggerFactory); - mock.Setup(x => x.GetInstance(typeof (IProfilingLogger))).Returns(new ProfilingLogger(logger, Mock.Of())); - mock.Setup(x => x.GetInstance(typeof (IUmbracoDatabaseFactory))).Returns(f); - mock.Setup(x => x.GetInstance(typeof (IScopeProvider))).Returns(p); + mock.Setup(x => x.GetRequiredService(typeof (ILogger))).Returns(logger); + mock.Setup(x => x.GetRequiredService(typeof(ILoggerFactory))).Returns(loggerFactory); + mock.Setup(x => x.GetRequiredService(typeof (IProfilingLogger))).Returns(new ProfilingLogger(logger, Mock.Of())); + mock.Setup(x => x.GetRequiredService(typeof (IUmbracoDatabaseFactory))).Returns(f); + mock.Setup(x => x.GetRequiredService(typeof (IScopeProvider))).Returns(p); setup?.Invoke(mock); return mock.Object; } - private static IRegister MockRegister() + private static IServiceCollection MockRegister() { - return Mock.Of(); + return Mock.Of(); } private static TypeLoader MockTypeLoader() @@ -86,8 +88,8 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Components var factory = MockFactory(m => { - m.Setup(x => x.TryGetInstance(It.Is(t => t == typeof(ISomeResource)))).Returns(() => new SomeResource()); - m.Setup(x => x.GetInstance(It.IsAny())).Returns((type) => + m.Setup(x => x.GetService(It.Is(t => t == typeof(ISomeResource)))).Returns(() => new SomeResource()); + m.Setup(x => x.GetRequiredService(It.IsAny())).Returns((type) => { if (type == typeof(Composer1)) return new Composer1(); if (type == typeof(Composer5)) return new Composer5(); @@ -99,7 +101,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Components }); var builder = composition.WithCollectionBuilder(); - builder.RegisterWith(register); + builder.RegisterWith(ServiceCollectionRegistryAdapter.Wrap(register)); var components = builder.CreateCollection(factory); Assert.IsEmpty(components); @@ -208,8 +210,8 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Components var typeLoader = MockTypeLoader(); var factory = MockFactory(m => { - m.Setup(x => x.TryGetInstance(It.Is(t => t == typeof (ISomeResource)))).Returns(() => new SomeResource()); - m.Setup(x => x.GetInstance(It.IsAny())).Returns((type) => + m.Setup(x => x.GetService(It.Is(t => t == typeof (ISomeResource)))).Returns(() => new SomeResource()); + m.Setup(x => x.GetRequiredService(It.IsAny())).Returns((type) => { if (type == typeof(Composer1)) return new Composer1(); if (type == typeof(Composer5)) return new Composer5(); @@ -231,7 +233,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Components AssertTypeArray(TypeArray(), Composed); var builder = composition.WithCollectionBuilder(); - builder.RegisterWith(register); + builder.RegisterWith(ServiceCollectionRegistryAdapter.Wrap(register)); var components = builder.CreateCollection(factory); Assert.IsEmpty(Initialized); @@ -287,7 +289,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Components Composed.Clear(); composers.Compose(); var builder = composition.WithCollectionBuilder(); - builder.RegisterWith(register); + builder.RegisterWith(ServiceCollectionRegistryAdapter.Wrap(register)); var components = builder.CreateCollection(factory); Assert.AreEqual(3, Composed.Count); Assert.AreEqual(typeof(Composer4), Composed[0]); diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/CollectionBuildersTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/CollectionBuildersTests.cs index e046c15cb4..241ab5e6ec 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/CollectionBuildersTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/CollectionBuildersTests.cs @@ -1,13 +1,16 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.Extensions.DependencyInjection; using Moq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Logging; +using Umbraco.Infrastructure.Composing; using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.UnitTests.TestHelpers; namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing { @@ -28,7 +31,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing // factoryMock.Setup(x => x.GetInstance(typeof(Resolved4))).Returns(new Resolved4()); - var register = TestHelper.GetRegister(); + var register = TestHelper.GetServiceCollection(); _composition = new Composition(register, TestHelper.GetMockedTypeLoader(), Mock.Of(), Mock.Of(), TestHelper.IOHelper, AppCaches.NoCache); } @@ -355,10 +358,10 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing using (factory.BeginScope()) { - var col1 = factory.GetInstance(); + var col1 = factory.GetRequiredService(); AssertCollection(col1, typeof(Resolved1), typeof(Resolved2)); - var col2 = factory.GetInstance(); + var col2 = factory.GetRequiredService(); AssertCollection(col2, typeof(Resolved1), typeof(Resolved2)); AssertSameCollection(factory, col1, col2); @@ -379,10 +382,10 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing var factory = _composition.CreateFactory(); - var col1 = factory.GetInstance(); + var col1 = factory.GetRequiredService(); AssertCollection(col1, typeof(Resolved1), typeof(Resolved2)); - var col2 = factory.GetInstance(); + var col2 = factory.GetRequiredService(); AssertCollection(col1, typeof(Resolved1), typeof(Resolved2)); AssertNotSameCollection(col1, col2); @@ -414,23 +417,23 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing TestCollection col1A, col1B; - var factory = _composition.CreateFactory(); + var wrapper = (ServiceProviderFactoryAdapter)_composition.CreateFactory(); - using (factory.BeginScope()) + using (var scope = wrapper.ServiceProvider.CreateScope()) { - col1A = factory.GetInstance(); - col1B = factory.GetInstance(); + col1A = scope.ServiceProvider.GetRequiredService(); + col1B = scope.ServiceProvider.GetRequiredService(); AssertCollection(col1A, typeof(Resolved1), typeof(Resolved2)); AssertCollection(col1B, typeof(Resolved1), typeof(Resolved2)); - AssertSameCollection(factory, col1A, col1B); + AssertSameCollection(wrapper, col1A, col1B); } TestCollection col2; - using (factory.BeginScope()) + using (var scope = wrapper.ServiceProvider.CreateScope()) { - col2 = factory.GetInstance(); + col2 = scope.ServiceProvider.GetRequiredService(); } AssertCollection(col2, typeof(Resolved1), typeof(Resolved2)); @@ -475,8 +478,8 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing { Assert.AreSame(col1A[i], col2A[i]); - var itemA = factory.GetInstance(col1A[i].GetType()); - var itemB = factory.GetInstance(col2A[i].GetType()); + var itemA = factory.GetRequiredService(col1A[i].GetType()); + var itemB = factory.GetRequiredService(col2A[i].GetType()); Assert.AreSame(itemA, itemB); } diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ContainerConformingTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ContainerConformingTests.cs deleted file mode 100644 index a091a22199..0000000000 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/ContainerConformingTests.cs +++ /dev/null @@ -1,387 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Composing; -using Umbraco.Tests.TestHelpers; - -namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing -{ - [TestFixture] - public class ContainerConformingTests - { - // tests that a container conforms - - private IRegister GetRegister() => TestHelper.GetRegister(); - - [Test] - public void CanRegisterAndGet() - { - var register = GetRegister(); - - register.Register(); - - var factory = register.CreateFactory(); - - var thing = factory.GetInstance(); - Assert.IsNotNull(thing); - Assert.IsInstanceOf(thing); - } - - [Test] - public void CanRegisterAndGetLazy() - { - var register = GetRegister(); - - register.Register(); - - var factory = register.CreateFactory(); - - var lazyThing = factory.GetInstance>(); - Assert.IsNotNull(lazyThing); - Assert.IsInstanceOf>(lazyThing); - var thing = lazyThing.Value; - Assert.IsNotNull(thing); - Assert.IsInstanceOf(thing); - } - - [Test] - public void CannotRegistedAndGetBase() - { - var register = GetRegister(); - - register.Register(); - - var factory = register.CreateFactory(); - - Assert.IsNull(factory.TryGetInstance()); - } - - [Test] - public void CannotRegisterAndGetInterface() - { - var register = GetRegister(); - - register.Register(); - - var factory = register.CreateFactory(); - - Assert.IsNull(factory.TryGetInstance()); - } - - [Test] - public void CanRegisterAndGetAllBase() - { - var register = GetRegister(); - - register.Register(); - - var factory = register.CreateFactory(); - - var things = factory.GetAllInstances(); - Assert.AreEqual(1, things.Count()); - - // lightInject: would be zero with option EnableVariance set to false - } - - [Test] - public void CanRegisterAndGetAllInterface() - { - var register = GetRegister(); - - register.Register(); - - var factory = register.CreateFactory(); - - var things = factory.GetAllInstances(); - Assert.AreEqual(1, things.Count()); - - // lightInject: would be zero with option EnableVariance set to false - } - - [Test] - public void CanRegisterBaseAndGet() - { - var register = GetRegister(); - - register.Register(); - - var factory = register.CreateFactory(); - - var thing = factory.GetInstance(); - Assert.IsNotNull(thing); - Assert.IsInstanceOf(thing); - } - - [Test] - public void CanRegisterInterfaceAndGet() - { - var register = GetRegister(); - - register.Register(); - - var factory = register.CreateFactory(); - - var thing = factory.GetInstance(); - Assert.IsNotNull(thing); - Assert.IsInstanceOf(thing); - } - - [Test] - public void NonSingletonServiceIsNotUnique() - { - var register = GetRegister(); - - register.Register(); - register.Register(); - - var factory = register.CreateFactory(); - - var things = factory.GetInstance>(); - Assert.AreEqual(2, things.Count()); - - Assert.IsNull(factory.TryGetInstance()); - } - - [Test] - public void SingletonServiceIsUnique() // FIXME: but what is LightInject actually doing - { - var register = GetRegister(); - - // FIXME: LightInject is 'unique' per serviceType+serviceName - // but that's not how all containers work - // and we should not rely on it - // if we need unique, use RegisterUnique - - // for Core services that ppl may want to redefine in components, - // it is important to be able to have a unique, singleton implementation, - // and to redefine it - how it's done at container's level depends - // on each container - - // redefine the service - register.Register(Lifetime.Singleton); - register.Register(Lifetime.Singleton); - - var factory = register.CreateFactory(); - - var things = factory.GetInstance>(); - Assert.AreEqual(1, things.Count()); - - var thing = factory.GetInstance(); - Assert.IsInstanceOf(thing); - } - - [Test] - public void SingletonImplementationIsNotUnique() - { - var register = GetRegister(); - - // define two implementations - register.Register(Lifetime.Singleton); - register.Register(Lifetime.Singleton); - - var factory = register.CreateFactory(); - - var things = factory.GetInstance>(); - Assert.AreEqual(2, things.Count()); - - Assert.IsNull(factory.TryGetInstance()); - } - - [Test] - public void ActualInstanceIsNotUnique() - { - var register = GetRegister(); - - // define two instances - register.Register(typeof(Thing1), new Thing1()); - register.Register(typeof(Thing1), new Thing2()); - - var factory = register.CreateFactory(); - - var things = factory.GetInstance>(); - //Assert.AreEqual(2, things.Count()); - Assert.AreEqual(1, things.Count()); // well, yes they are unique? - - Assert.IsNull(factory.TryGetInstance()); - } - - [Test] - public void InterfaceInstanceIsNotUnique() - { - var register = GetRegister(); - - // define two instances - register.Register(typeof(IThing), new Thing1()); - register.Register(typeof(IThing), new Thing2()); - - var factory = register.CreateFactory(); - - var things = factory.GetInstance>(); - //Assert.AreEqual(2, things.Count()); - Assert.AreEqual(1, things.Count()); // well, yes they are unique? - - //Assert.IsNull(factory.TryGetInstance()); - Assert.IsNotNull(factory.TryGetInstance()); // well, what? - } - - [Test] - public void CanInjectEnumerableOfBase() - { - var register = GetRegister(); - - register.Register(); - register.Register(); - register.Register(); - - var factory = register.CreateFactory(); - - var needThings = factory.GetInstance(); - Assert.AreEqual(2, needThings.Things.Count()); - } - - [Test] - public void CanGetEnumerableOfBase() - { - var register = GetRegister(); - - register.Register(); - register.Register(); - - var factory = register.CreateFactory(); - - var things = factory.GetInstance>(); - Assert.AreEqual(2, things. Count()); - } - - [Test] - public void CanGetEmptyEnumerableOfBase() - { - var register = GetRegister(); - var factory = register.CreateFactory(); - - var things = factory.GetInstance>(); - Assert.AreEqual(0, things.Count()); - } - - [Test] - public void CanGetEmptyAllInstancesOfBase() - { - var register = GetRegister(); - var factory = register.CreateFactory(); - - var things = factory.GetAllInstances(); - Assert.AreEqual(0, things.Count()); - } - - [Test] - public void CanTryGetEnumerableOfBase() - { - var register = GetRegister(); - - register.Register(); - register.Register(); - - var factory = register.CreateFactory(); - - var things = factory.TryGetInstance>(); - Assert.AreEqual(2, things.Count()); - } - - [Test] - public void CanRegisterSingletonInterface() - { - var register = GetRegister(); - register.Register(Lifetime.Singleton); - var factory = register.CreateFactory(); - var s1 = factory.GetInstance(); - var s2 = factory.GetInstance(); - Assert.AreSame(s1, s2); - } - - [Test] - public void CanRegisterSingletonClass() - { - var register = GetRegister(); - register.Register(Lifetime.Singleton); - var factory = register.CreateFactory(); - var s1 = factory.GetInstance(); - var s2 = factory.GetInstance(); - Assert.AreSame(s1, s2); - } - - [Test] - public void CanReRegisterSingletonInterface() - { - var register = GetRegister(); - register.Register(Lifetime.Singleton); - register.Register(Lifetime.Singleton); - var factory = register.CreateFactory(); - var s = factory.GetInstance(); - Assert.IsInstanceOf(s); - } - - [Test] - public void CanRegisterSingletonWithCreate() - { - var register = GetRegister(); - register.Register(c => c.CreateInstance(new Thing1()), Lifetime.Singleton); - var factory = register.CreateFactory(); - var s1 = factory.GetInstance(); - var s2 = factory.GetInstance(); - Assert.AreSame(s1, s2); - } - - [Test] - public void CanRegisterMultipleSameTypeParametersWithCreateInstance() - { - var register = GetRegister(); - - register.Register(c => - { - const string param1 = "param1"; - const string param2 = "param2"; - - return c.CreateInstance(param1, param2); - }); - - var factory = register.CreateFactory(); - var instance = factory.GetInstance(); - Assert.AreNotEqual(instance.Thing, instance.AnotherThing); - } - - public interface IThing { } - - public abstract class ThingBase : IThing { } - public class Thing1 : ThingBase { } - public class Thing2 : ThingBase { } - - public class Thing3 : ThingBase - { - public Thing3(Thing1 thing) { } - } - - public class NeedThings - { - public NeedThings(IEnumerable things) - { - Things = things; - } - - public IEnumerable Things { get; } - } - - public class Thing4 : ThingBase - { - public readonly string Thing; - public readonly string AnotherThing; - - public Thing4(string thing, string anotherThing) - { - Thing = thing; - AnotherThing = anotherThing; - } - } - } -} diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/LazyCollectionBuilderTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/LazyCollectionBuilderTests.cs index e1a3f75ba2..f73fcd83c0 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/LazyCollectionBuilderTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/LazyCollectionBuilderTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.Extensions.DependencyInjection; using Moq; using NUnit.Framework; using Umbraco.Core; @@ -8,15 +9,16 @@ using Umbraco.Core.Cache; using Umbraco.Core.Composing; using Umbraco.Core.Logging; using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.UnitTests.TestHelpers; namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing { [TestFixture] public class LazyCollectionBuilderTests { - private IRegister CreateRegister() + private IServiceCollection CreateRegister() { - return TestHelper.GetRegister(); + return TestHelper.GetServiceCollection(); } // note @@ -37,13 +39,13 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing var factory = composition.CreateFactory(); - var values = factory.GetInstance(); + var values = factory.GetRequiredService(); Assert.AreEqual(3, values.Count()); Assert.IsTrue(values.Select(x => x.GetType()) .ContainsAll(new[] { typeof(TransientObject1), typeof(TransientObject2), typeof(TransientObject3) })); - var other = factory.GetInstance(); + var other = factory.GetRequiredService(); Assert.AreNotSame(values, other); // transient var o1 = other.FirstOrDefault(x => x is TransientObject1); Assert.IsFalse(values.Contains(o1)); // transient @@ -62,13 +64,13 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing var factory = composition.CreateFactory(); - var values = factory.GetInstance(); + var values = factory.GetRequiredService(); Assert.AreEqual(3, values.Count()); Assert.IsTrue(values.Select(x => x.GetType()) .ContainsAll(new[] { typeof(TransientObject1), typeof(TransientObject2), typeof(TransientObject3) })); - var other = factory.GetInstance(); + var other = factory.GetRequiredService(); Assert.AreNotSame(values, other); // transient var o1 = other.FirstOrDefault(x => x is TransientObject1); Assert.IsFalse(values.Contains(o1)); // transient @@ -88,13 +90,13 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing var factory = composition.CreateFactory(); - var values = factory.GetInstance(); + var values = factory.GetRequiredService(); Assert.AreEqual(3, values.Count()); Assert.IsTrue(values.Select(x => x.GetType()) .ContainsAll(new[] { typeof(TransientObject1), typeof(TransientObject2), typeof(TransientObject3) })); - var other = factory.GetInstance(); + var other = factory.GetRequiredService(); Assert.AreNotSame(values, other); // transient var o1 = other.FirstOrDefault(x => x is TransientObject1); Assert.IsFalse(values.Contains(o1)); // transient @@ -135,7 +137,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing var factory = composition.CreateFactory(); - var values = factory.GetInstance(); + var values = factory.GetRequiredService(); Assert.AreEqual(2, values.Count()); Assert.IsFalse(values.Select(x => x.GetType()) @@ -143,7 +145,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing Assert.IsTrue(values.Select(x => x.GetType()) .ContainsAll(new[] { typeof(TransientObject1), typeof(TransientObject2) })); - var other = factory.GetInstance(); + var other = factory.GetRequiredService(); Assert.AreNotSame(values, other); // transient var o1 = other.FirstOrDefault(x => x is TransientObject1); Assert.IsFalse(values.Contains(o1)); // transient diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/PackageActionCollectionTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/PackageActionCollectionTests.cs index a144f9340a..5b2aae9fc2 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/PackageActionCollectionTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Composing/PackageActionCollectionTests.cs @@ -10,6 +10,7 @@ using Umbraco.Core.Composing; using Umbraco.Core.Logging; using Umbraco.Core.PackageActions; using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.UnitTests.TestHelpers; namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing { @@ -19,7 +20,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing [Test] public void PackageActionCollectionBuilderWorks() { - var container = TestHelper.GetRegister(); + var container = TestHelper.GetServiceCollection(); var composition = new Composition(container, TestHelper.GetMockedTypeLoader(), Mock.Of(), Mock.Of(), TestHelper.IOHelper, AppCaches.NoCache); @@ -29,7 +30,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Core.Composing var factory = composition.CreateFactory(); - var actions = factory.GetInstance(); + var actions = factory.GetRequiredService(); Assert.AreEqual(2, actions.Count()); // order is unspecified, but both must be there diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs index 75e4d1cfd2..3ac7efd467 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedContentCacheTests.cs @@ -61,7 +61,7 @@ namespace Umbraco.Tests.Cache.PublishedCache _httpContextFactory = new FakeHttpContextFactory("~/Home"); var globalSettings = new GlobalSettings(); - var umbracoContextAccessor = Factory.GetInstance(); + var umbracoContextAccessor = Factory.GetRequiredService(); _xml = new XmlDocument(); _xml.LoadXml(GetXml()); @@ -70,7 +70,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var domainCache = new DomainCache(Mock.Of(), DefaultCultureAccessor); var publishedShapshot = new PublishedSnapshot( new PublishedContentCache(xmlStore, domainCache, appCache, globalSettings, ContentTypesCache, null, VariationContextAccessor, null), - new PublishedMediaCache(xmlStore, Mock.Of(), Mock.Of(), appCache, ContentTypesCache, Factory.GetInstance(), umbracoContextAccessor, VariationContextAccessor), + new PublishedMediaCache(xmlStore, Mock.Of(), Mock.Of(), appCache, ContentTypesCache, Factory.GetRequiredService(), umbracoContextAccessor, VariationContextAccessor), new PublishedMemberCache(null, appCache, Mock.Of(), ContentTypesCache, Mock.Of(), VariationContextAccessor), domainCache); var publishedSnapshotService = new Mock(); diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs index 20f6892e0c..810532367a 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs @@ -81,7 +81,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var mChild2 = MakeNewMedia("Child2", mType, user, mRoot2.Id); var ctx = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(new XmlStore((XmlDocument) null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance(), VariationContextAccessor); + var cache = new PublishedMediaCache(new XmlStore((XmlDocument) null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetRequiredService(), Factory.GetRequiredService(), VariationContextAccessor); var roots = cache.GetAtRoot(); Assert.AreEqual(2, roots.Count()); Assert.IsTrue(roots.Select(x => x.Id).ContainsAll(new[] {mRoot1.Id, mRoot2.Id})); @@ -99,7 +99,7 @@ namespace Umbraco.Tests.Cache.PublishedCache //var publishedMedia = PublishedMediaTests.GetNode(mRoot.Id, GetUmbracoContext("/test", 1234)); var umbracoContext = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance(), VariationContextAccessor); + var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetRequiredService(), Factory.GetRequiredService(), VariationContextAccessor); var publishedMedia = cache.GetById(mRoot.Id); Assert.IsNotNull(publishedMedia); @@ -210,7 +210,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var result = new SearchResult("1234", 1, () => fields.ToDictionary(x => x.Key, x => new List { x.Value })); - var store = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance(), VariationContextAccessor); + var store = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetRequiredService(), Factory.GetRequiredService(), VariationContextAccessor); var doc = store.CreateFromCacheValues(store.ConvertFromSearchResult(result)); DoAssert(doc, 1234, key, null, 0, "/media/test.jpg", "Image", 23, "Shannon", "Shannon", "-1,1234", DateTime.Parse("2012-07-17T10:34:09"), DateTime.Parse("2012-07-16T10:34:09"), 2); @@ -226,7 +226,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var xmlDoc = GetMediaXml(); ((XmlElement)xmlDoc.DocumentElement.FirstChild).SetAttribute("key", key.ToString()); var navigator = xmlDoc.SelectSingleNode("/root/Image").CreateNavigator(); - var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance(),VariationContextAccessor); + var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetRequiredService(), Factory.GetRequiredService(),VariationContextAccessor); var doc = cache.CreateFromCacheValues(cache.ConvertFromXPathNavigator(navigator, true)); DoAssert(doc, 2000, key, null, 2, "image1", "Image", 23, "Shannon", "Shannon", "-1,2000", DateTime.Parse("2012-06-12T14:13:17"), DateTime.Parse("2012-07-20T18:50:43"), 1); diff --git a/src/Umbraco.Tests/IO/FileSystemsTests.cs b/src/Umbraco.Tests/IO/FileSystemsTests.cs index d35f950e75..039ded5e4e 100644 --- a/src/Umbraco.Tests/IO/FileSystemsTests.cs +++ b/src/Umbraco.Tests/IO/FileSystemsTests.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Text; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Moq; @@ -14,7 +15,9 @@ using Umbraco.Core.IO; using Umbraco.Core.IO.MediaPathSchemes; using Umbraco.Core.Logging; using Umbraco.Core.Services; +using Umbraco.Infrastructure.Composing; using Umbraco.Tests.TestHelpers; +using Umbraco.Web; using FileSystems = Umbraco.Core.IO.FileSystems; namespace Umbraco.Tests.IO @@ -30,10 +33,17 @@ namespace Umbraco.Tests.IO { _register = TestHelper.GetRegister(); - var composition = new Composition(_register, TestHelper.GetMockedTypeLoader(), Mock.Of(), Mock.Of(), TestHelper.IOHelper, AppCaches.NoCache); + var composition = new Composition( + (_register as ServiceCollectionRegistryAdapter).Services, + TestHelper.GetMockedTypeLoader(), + Mock.Of(), + Mock.Of(), + TestHelper.IOHelper, + AppCaches.NoCache + ); composition.Register(_ => Mock.Of()); - composition.Register(NullLoggerFactory.Instance); + composition.Services.AddTransient(); composition.Register(typeof(ILogger<>), typeof(Logger<>)); composition.Register(_ => TestHelper.ShortStringHelper); composition.Register(_ => TestHelper.IOHelper); @@ -63,34 +73,34 @@ namespace Umbraco.Tests.IO _register.DisposeIfDisposable(); } - private FileSystems FileSystems => _factory.GetInstance(); + private FileSystems FileSystems => _factory.GetRequiredService(); [Test] public void Can_Get_MediaFileSystem() { - var fileSystem = _factory.GetInstance(); + var fileSystem = _factory.GetRequiredService(); Assert.NotNull(fileSystem); } [Test] public void Can_Get_IMediaFileSystem() { - var fileSystem = _factory.GetInstance(); + var fileSystem = _factory.GetRequiredService(); Assert.NotNull(fileSystem); } [Test] public void IMediaFileSystem_Is_Singleton() { - var fileSystem1 = _factory.GetInstance(); - var fileSystem2 = _factory.GetInstance(); + var fileSystem1 = _factory.GetRequiredService(); + var fileSystem2 = _factory.GetRequiredService(); Assert.AreSame(fileSystem1, fileSystem2); } [Test] public void Can_Unwrap_MediaFileSystem() { - var fileSystem = _factory.GetInstance(); + var fileSystem = _factory.GetRequiredService(); var unwrapped = fileSystem.Unwrap(); Assert.IsNotNull(unwrapped); var physical = unwrapped as PhysicalFileSystem; @@ -100,13 +110,13 @@ namespace Umbraco.Tests.IO [Test] public void Can_Delete_MediaFiles() { - var fs = _factory.GetInstance(); + var fs = _factory.GetRequiredService(); var ms = new MemoryStream(Encoding.UTF8.GetBytes("test")); var virtPath = fs.GetMediaPath("file.txt", Guid.NewGuid(), Guid.NewGuid()); fs.AddFile(virtPath, ms); // ~/media/1234/file.txt exists - var ioHelper = _factory.GetInstance(); + var ioHelper = _factory.GetRequiredService(); var physPath = ioHelper.MapPath(Path.Combine("media", virtPath)); Assert.IsTrue(File.Exists(physPath)); @@ -114,7 +124,7 @@ namespace Umbraco.Tests.IO fs.DeleteMediaFiles(new[] { virtPath }); Assert.IsFalse(File.Exists(physPath)); - var scheme = _factory.GetInstance(); + var scheme = _factory.GetRequiredService(); if (scheme is UniqueMediaPathScheme) { // ~/media/1234 is *not* gone diff --git a/src/Umbraco.Tests/Issues/U9560.cs b/src/Umbraco.Tests/Issues/U9560.cs index c750201b0c..279d6798aa 100644 --- a/src/Umbraco.Tests/Issues/U9560.cs +++ b/src/Umbraco.Tests/Issues/U9560.cs @@ -27,7 +27,7 @@ namespace Umbraco.Tests.Issues var aliasName = string.Empty; // read fields, same as what we do with PetaPoco Fetch - using (var db = Factory.GetInstance().CreateDatabase()) + using (var db = Factory.GetRequiredService().CreateDatabase()) { db.OpenSharedConnection(); try @@ -55,7 +55,7 @@ namespace Umbraco.Tests.Issues Assert.AreEqual("Alias", aliasName); // try differently - using (var db = Factory.GetInstance().CreateDatabase()) + using (var db = Factory.GetRequiredService().CreateDatabase()) { db.OpenSharedConnection(); try diff --git a/src/Umbraco.Tests/Models/ContentXmlTest.cs b/src/Umbraco.Tests/Models/ContentXmlTest.cs index 70307b9bad..0aff0e7ad3 100644 --- a/src/Umbraco.Tests/Models/ContentXmlTest.cs +++ b/src/Umbraco.Tests/Models/ContentXmlTest.cs @@ -29,7 +29,7 @@ namespace Umbraco.Tests.Models var urlName = content.GetUrlSegment(ShortStringHelper, new[]{new DefaultUrlSegmentProvider(ShortStringHelper) }); // Act - XElement element = content.ToXml(Factory.GetInstance()); + XElement element = content.ToXml(Factory.GetRequiredService()); // Assert Assert.That(element, Is.Not.Null); diff --git a/src/Umbraco.Tests/Models/MediaXmlTest.cs b/src/Umbraco.Tests/Models/MediaXmlTest.cs index 646dc7f2a0..83184dcb82 100644 --- a/src/Umbraco.Tests/Models/MediaXmlTest.cs +++ b/src/Umbraco.Tests/Models/MediaXmlTest.cs @@ -51,7 +51,7 @@ namespace Umbraco.Tests.Models var urlName = media.GetUrlSegment(ShortStringHelper, new[] { new DefaultUrlSegmentProvider(ShortStringHelper) }); // Act - XElement element = media.ToXml(Factory.GetInstance()); + XElement element = media.ToXml(Factory.GetRequiredService()); // Assert Assert.That(element, Is.Not.Null); diff --git a/src/Umbraco.Tests/Packaging/PackageDataInstallationTests.cs b/src/Umbraco.Tests/Packaging/PackageDataInstallationTests.cs index 6aaab9a698..0576aa45d6 100644 --- a/src/Umbraco.Tests/Packaging/PackageDataInstallationTests.cs +++ b/src/Umbraco.Tests/Packaging/PackageDataInstallationTests.cs @@ -72,7 +72,7 @@ namespace Umbraco.Tests.Packaging Composition.ComposeFileSystems(); } - private PackageDataInstallation PackageDataInstallation => Factory.GetInstance(); + private PackageDataInstallation PackageDataInstallation => Factory.GetRequiredService(); [Test] public void Can_Import_uBlogsy_ContentTypes_And_Verify_Structure() @@ -425,7 +425,7 @@ namespace Umbraco.Tests.Packaging string strXml = ImportResources.SingleDocType; var docTypeElement = XElement.Parse(strXml); - var serializer = Factory.GetInstance(); + var serializer = Factory.GetRequiredService(); // Act var contentTypes = PackageDataInstallation.ImportDocumentType(docTypeElement, 0); diff --git a/src/Umbraco.Tests/Packaging/PackageInstallationTest.cs b/src/Umbraco.Tests/Packaging/PackageInstallationTest.cs index 4dfc3503aa..d2b88fabff 100644 --- a/src/Umbraco.Tests/Packaging/PackageInstallationTest.cs +++ b/src/Umbraco.Tests/Packaging/PackageInstallationTest.cs @@ -55,11 +55,11 @@ namespace Umbraco.Tests.Packaging NullLoggerFactory.Instance.CreateLogger(), NullLoggerFactory.Instance, ServiceContext.FileService, ServiceContext.MacroService, ServiceContext.LocalizationService, ServiceContext.DataTypeService, ServiceContext.EntityService, ServiceContext.ContentTypeService, ServiceContext.ContentService, - Factory.GetInstance(), - Factory.GetInstance(), - Factory.GetInstance(), + Factory.GetRequiredService(), + Factory.GetRequiredService(), + Factory.GetRequiredService(), Microsoft.Extensions.Options.Options.Create(new GlobalSettings()), - Factory.GetInstance()); + Factory.GetRequiredService()); private IPackageInstallation PackageInstallation => new PackageInstallation( PackageDataInstallation, diff --git a/src/Umbraco.Tests/Published/ConvertersTests.cs b/src/Umbraco.Tests/Published/ConvertersTests.cs index 3ddefd9fa5..1541f5d446 100644 --- a/src/Umbraco.Tests/Published/ConvertersTests.cs +++ b/src/Umbraco.Tests/Published/ConvertersTests.cs @@ -15,8 +15,10 @@ using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; using Umbraco.Core.Strings; +using Umbraco.Infrastructure.Composing; using Umbraco.Tests.PublishedContent; using Umbraco.Tests.TestHelpers; +using Umbraco.Web; using Umbraco.Web.PublishedCache; namespace Umbraco.Tests.Published @@ -32,7 +34,14 @@ namespace Umbraco.Tests.Published // Current.Reset(); var register = TestHelper.GetRegister(); - var composition = new Composition(register, TestHelper.GetMockedTypeLoader(), Mock.Of(), Mock.Of(), Mock.Of(), AppCaches.NoCache); + var composition = new Composition( + (register as ServiceCollectionRegistryAdapter).Services, + TestHelper.GetMockedTypeLoader(), + Mock.Of(), + Mock.Of(), + Mock.Of(), + AppCaches.NoCache + ); composition.WithCollectionBuilder() .Append() @@ -45,7 +54,7 @@ namespace Umbraco.Tests.Published }, Mock.Of()); register.Register(f => factory); - var registerFactory = composition.CreateFactory(); + var cacheMock = new Mock(); var cacheContent = new Dictionary(); @@ -56,7 +65,8 @@ namespace Umbraco.Tests.Published publishedSnapshotAccessorMock.Setup(x => x.PublishedSnapshot).Returns(publishedSnapshotMock.Object); register.Register(f => publishedSnapshotAccessorMock.Object); - var converters = registerFactory.GetInstance(); + var registerFactory = composition.CreateFactory(); + var converters = registerFactory.GetRequiredService(); var dataTypeServiceMock = new Mock(); var dataType1 = new DataType(new VoidEditor(NullLoggerFactory.Instance, dataTypeServiceMock.Object, @@ -93,7 +103,7 @@ namespace Umbraco.Tests.Published Properties = new[] { new SolidPublishedProperty { Alias = "prop2", SolidHasValue = true, SolidValue = "1003" } } }; - var publishedModelFactory = registerFactory.GetInstance(); + var publishedModelFactory = registerFactory.GetRequiredService(); cacheContent[cnt1.Id] = cnt1.CreateModel(publishedModelFactory); cacheContent[cnt2.Id] = cnt2.CreateModel(publishedModelFactory); diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs index 72f7d0e46c..9e36e867a4 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs @@ -61,7 +61,7 @@ namespace Umbraco.Tests.PublishedContent var hostingEnvironment = Mock.Of(); - Mock.Get(factory).Setup(x => x.GetInstance(typeof(IPublishedModelFactory))).Returns(PublishedModelFactory); + Mock.Get(factory).Setup(x => x.GetRequiredService(typeof(IPublishedModelFactory))).Returns(PublishedModelFactory); var runtime = Mock.Of(); Mock.Get(runtime).Setup(x => x.Level).Returns(RuntimeLevel.Run); @@ -172,7 +172,7 @@ namespace Umbraco.Tests.PublishedContent // invariant is the current default _variationAccesor.VariationContext = new VariationContext(); - Mock.Get(factory).Setup(x => x.GetInstance(typeof(IVariationContextAccessor))).Returns(_variationAccesor); + Mock.Get(factory).Setup(x => x.GetRequiredService(typeof(IVariationContextAccessor))).Returns(_variationAccesor); } private IEnumerable GetNestedVariantKits() diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs index 6b97f4d1ed..4d5fcc6515 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs @@ -53,7 +53,7 @@ namespace Umbraco.Tests.PublishedContent Current.Factory = factory; var publishedModelFactory = new NoopPublishedModelFactory(); - Mock.Get(factory).Setup(x => x.GetInstance(typeof(IPublishedModelFactory))).Returns(publishedModelFactory); + Mock.Get(factory).Setup(x => x.GetRequiredService(typeof(IPublishedModelFactory))).Returns(publishedModelFactory); // create a content node kit var kit = new ContentNodeKit @@ -212,7 +212,7 @@ namespace Umbraco.Tests.PublishedContent // invariant is the current default _variationAccesor.VariationContext = new VariationContext(); - Mock.Get(factory).Setup(x => x.GetInstance(typeof(IVariationContextAccessor))).Returns(_variationAccesor); + Mock.Get(factory).Setup(x => x.GetRequiredService(typeof(IVariationContextAccessor))).Returns(_variationAccesor); } [Test] diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs index 92e17ec9cd..2084a809b3 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentSnapshotTestBase.cs @@ -45,7 +45,7 @@ namespace Umbraco.Tests.PublishedContent { base.Compose(); - Composition.RegisterUnique(f => new PublishedModelFactory(f.GetInstance().GetTypes(), f.GetInstance())); + Composition.RegisterUnique(f => new PublishedModelFactory(f.GetRequiredService().GetTypes(), f.GetRequiredService())); } protected override TypeLoader CreateTypeLoader(IIOHelper ioHelper, ITypeFinder typeFinder, IAppPolicyCache runtimeCache, ILogger logger, IProfilingLogger profilingLogger , IHostingEnvironment hostingEnvironment) diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs index 058cda093e..b8011d160d 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs @@ -43,7 +43,7 @@ namespace Umbraco.Tests.PublishedContent { base.Initialize(); - var converters = Factory.GetInstance(); + var converters = Factory.GetRequiredService(); var umbracoContextAccessor = Mock.Of(); var publishedUrlProvider = Mock.Of(); var loggerFactory = NullLoggerFactory.Instance; diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs index 982be79a33..5bf7120e02 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs @@ -44,7 +44,7 @@ namespace Umbraco.Tests.PublishedContent _publishedSnapshotAccessorMock = new Mock(); Composition.RegisterUnique(_publishedSnapshotAccessorMock.Object); - Composition.RegisterUnique(f => new PublishedModelFactory(f.GetInstance().GetTypes(), f.GetInstance())); + Composition.RegisterUnique(f => new PublishedModelFactory(f.GetRequiredService().GetTypes(), f.GetRequiredService())); Composition.RegisterUnique(); Composition.RegisterUnique(); @@ -73,7 +73,7 @@ namespace Umbraco.Tests.PublishedContent { base.Initialize(); - var factory = Factory.GetInstance() as PublishedContentTypeFactory; + var factory = Factory.GetRequiredService() as PublishedContentTypeFactory; // need to specify a custom callback for unit tests // AutoPublishedContentTypes generates properties automatically @@ -904,7 +904,7 @@ namespace Umbraco.Tests.PublishedContent [Test] public void FragmentProperty() { - var factory = Factory.GetInstance() as PublishedContentTypeFactory; + var factory = Factory.GetRequiredService() as PublishedContentTypeFactory; IEnumerable CreatePropertyTypes(IPublishedContentType contentType) { @@ -928,7 +928,7 @@ namespace Umbraco.Tests.PublishedContent [Test] public void Fragment2() { - var factory = Factory.GetInstance() as PublishedContentTypeFactory; + var factory = Factory.GetRequiredService() as PublishedContentTypeFactory; IEnumerable CreatePropertyTypes(IPublishedContentType contentType) { diff --git a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs index 854e24d162..a8eaff34bf 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs @@ -72,7 +72,7 @@ namespace Umbraco.Tests.PublishedContent { var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, - Factory.GetInstance(), Factory.GetInstance(), VariationContextAccessor); + Factory.GetRequiredService(), Factory.GetRequiredService(), VariationContextAccessor); var doc = cache.GetById(id); Assert.IsNotNull(doc); return doc; @@ -117,7 +117,7 @@ namespace Umbraco.Tests.PublishedContent [Test] public void Ensure_Children_Sorted_With_Examine() { - var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetInstance(), IndexInitializer.GetMockMediaService()); + var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetRequiredService(), IndexInitializer.GetMockMediaService()); using (var luceneDir = new RandomIdRamDirectory()) using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, HostingEnvironment, RuntimeState, luceneDir, @@ -129,7 +129,7 @@ namespace Umbraco.Tests.PublishedContent var searcher = indexer.GetSearcher(); var ctx = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); + var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryAppCache(), ContentTypesCache, Factory.GetRequiredService(), Factory.GetRequiredService()); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace var publishedMedia = cache.GetById(1111); @@ -146,7 +146,7 @@ namespace Umbraco.Tests.PublishedContent [Test] public void Do_Not_Find_In_Recycle_Bin() { - var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetInstance(), IndexInitializer.GetMockMediaService()); + var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetRequiredService(), IndexInitializer.GetMockMediaService()); using (var luceneDir = new RandomIdRamDirectory()) using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, HostingEnvironment, RuntimeState, luceneDir, @@ -159,7 +159,7 @@ namespace Umbraco.Tests.PublishedContent var searcher = indexer.GetSearcher(); var ctx = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); + var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryAppCache(), ContentTypesCache, Factory.GetRequiredService(), Factory.GetRequiredService()); //ensure it is found var publishedMedia = cache.GetById(3113); @@ -194,7 +194,7 @@ namespace Umbraco.Tests.PublishedContent [Test] public void Children_With_Examine() { - var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetInstance(), IndexInitializer.GetMockMediaService()); + var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetRequiredService(), IndexInitializer.GetMockMediaService()); using (var luceneDir = new RandomIdRamDirectory()) using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, HostingEnvironment, RuntimeState, luceneDir, @@ -206,7 +206,7 @@ namespace Umbraco.Tests.PublishedContent var searcher = indexer.GetSearcher(); var ctx = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); + var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryAppCache(), ContentTypesCache, Factory.GetRequiredService(), Factory.GetRequiredService()); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace var publishedMedia = cache.GetById(1111); @@ -222,7 +222,7 @@ namespace Umbraco.Tests.PublishedContent [Test] public void Descendants_With_Examine() { - var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetInstance(), IndexInitializer.GetMockMediaService()); + var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetRequiredService(), IndexInitializer.GetMockMediaService()); using (var luceneDir = new RandomIdRamDirectory()) using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, HostingEnvironment, RuntimeState, luceneDir, @@ -234,7 +234,7 @@ namespace Umbraco.Tests.PublishedContent var searcher = indexer.GetSearcher(); var ctx = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); + var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryAppCache(), ContentTypesCache, Factory.GetRequiredService(), Factory.GetRequiredService()); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace var publishedMedia = cache.GetById(1111); @@ -250,7 +250,7 @@ namespace Umbraco.Tests.PublishedContent [Test] public void DescendantsOrSelf_With_Examine() { - var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetInstance(), IndexInitializer.GetMockMediaService()); + var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetRequiredService(), IndexInitializer.GetMockMediaService()); using (var luceneDir = new RandomIdRamDirectory()) using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, HostingEnvironment, RuntimeState, luceneDir, @@ -262,7 +262,7 @@ namespace Umbraco.Tests.PublishedContent var searcher = indexer.GetSearcher(); var ctx = GetUmbracoContext("/test"); - var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); + var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryAppCache(), ContentTypesCache, Factory.GetRequiredService(), Factory.GetRequiredService()); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace var publishedMedia = cache.GetById(1111); @@ -278,7 +278,7 @@ namespace Umbraco.Tests.PublishedContent [Test] public void Ancestors_With_Examine() { - var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetInstance(), IndexInitializer.GetMockMediaService()); + var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetRequiredService(), IndexInitializer.GetMockMediaService()); using (var luceneDir = new RandomIdRamDirectory()) @@ -291,7 +291,7 @@ namespace Umbraco.Tests.PublishedContent var ctx = GetUmbracoContext("/test"); var searcher = indexer.GetSearcher(); - var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); + var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryAppCache(), ContentTypesCache, Factory.GetRequiredService(), Factory.GetRequiredService()); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace var publishedMedia = cache.GetById(3113); @@ -304,7 +304,7 @@ namespace Umbraco.Tests.PublishedContent [Test] public void AncestorsOrSelf_With_Examine() { - var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetInstance(), IndexInitializer.GetMockMediaService()); + var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetRequiredService(), IndexInitializer.GetMockMediaService()); using (var luceneDir = new RandomIdRamDirectory()) using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, HostingEnvironment, RuntimeState, luceneDir, @@ -317,7 +317,7 @@ namespace Umbraco.Tests.PublishedContent var ctx = GetUmbracoContext("/test"); var searcher = indexer.GetSearcher(); - var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance()); + var cache = new PublishedMediaCache(ServiceContext.MediaService, ServiceContext.UserService, searcher, new DictionaryAppCache(), ContentTypesCache, Factory.GetRequiredService(), Factory.GetRequiredService()); //we are using the media.xml media to test the examine results implementation, see the media.xml file in the ExamineHelpers namespace var publishedMedia = cache.GetById(3113); @@ -485,7 +485,7 @@ namespace Umbraco.Tests.PublishedContent "); var node = xml.DescendantsAndSelf("Image").Single(x => (int)x.Attribute("id") == nodeId); - var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance(), VariationContextAccessor); + var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetRequiredService(), Factory.GetRequiredService(), VariationContextAccessor); var nav = node.CreateNavigator(); @@ -505,7 +505,7 @@ namespace Umbraco.Tests.PublishedContent var errorXml = new XElement("error", string.Format("No media is maching '{0}'", 1234)); var nav = errorXml.CreateNavigator(); - var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance(), Factory.GetInstance(), VariationContextAccessor); + var publishedMedia = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment), ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetRequiredService(), Factory.GetRequiredService(), VariationContextAccessor); var converted = publishedMedia.ConvertFromXPathNodeIterator(nav.Select("/"), 1234); Assert.IsNull(converted); diff --git a/src/Umbraco.Tests/Routing/BaseUrlProviderTest.cs b/src/Umbraco.Tests/Routing/BaseUrlProviderTest.cs index 9860b5739f..8b05dd2c06 100644 --- a/src/Umbraco.Tests/Routing/BaseUrlProviderTest.cs +++ b/src/Umbraco.Tests/Routing/BaseUrlProviderTest.cs @@ -1,4 +1,5 @@ using System.Linq; +using Microsoft.Extensions.DependencyInjection; using Moq; using Umbraco.Core; using Umbraco.Core.Configuration.Models; @@ -19,7 +20,7 @@ namespace Umbraco.Tests.Routing protected override void Compose() { base.Compose(); - Composition.Register(); + Composition.Services.AddTransient(); } protected override void ComposeSettings() diff --git a/src/Umbraco.Tests/Routing/ContentFinderByIdTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByIdTests.cs index a21b36dcf5..c02626bab4 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByIdTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByIdTests.cs @@ -20,7 +20,7 @@ namespace Umbraco.Tests.Routing var publishedRouter = CreatePublishedRouter(); var frequest = publishedRouter.CreateRequest(umbracoContext); var webRoutingSettings = new WebRoutingSettings(); - var lookup = new ContentFinderByIdPath(Microsoft.Extensions.Options.Options.Create(webRoutingSettings), LoggerFactory.CreateLogger(), Factory.GetInstance()); + var lookup = new ContentFinderByIdPath(Microsoft.Extensions.Options.Options.Create(webRoutingSettings), LoggerFactory.CreateLogger(), Factory.GetRequiredService()); var result = lookup.TryFindContent(frequest); diff --git a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs index 73ca7ba03c..edcbf858e2 100644 --- a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs +++ b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs @@ -1,4 +1,5 @@ -using NUnit.Framework; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; using Microsoft.Extensions.Logging; using Umbraco.Core.Models; using Umbraco.Web.Routing; @@ -14,7 +15,7 @@ namespace Umbraco.Tests.Routing { base.Compose(); - Composition.Register(); + Composition.Services.AddTransient(); } private void SetDomains1() diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs index d74a8c68fe..e926557856 100644 --- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs +++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs @@ -155,12 +155,12 @@ namespace Umbraco.Tests.Routing var handler = new RenderRouteHandler(umbracoContext, new TestControllerFactory(umbracoContextAccessor, Mock.Of>(), context => { - return new CustomDocumentController(Factory.GetInstance>(), + return new CustomDocumentController(Factory.GetRequiredService>(), umbracoContextAccessor, - Factory.GetInstance(), - Factory.GetInstance(), - Factory.GetInstance(), - Factory.GetInstance()); + Factory.GetRequiredService(), + Factory.GetRequiredService(), + Factory.GetRequiredService(), + Factory.GetRequiredService()); }), ShortStringHelper); handler.GetHandlerForRoute(httpContext.Request.RequestContext, frequest); diff --git a/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs b/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs index 68c002fea3..4165b381ca 100644 --- a/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/UrlsProviderWithDomainsTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; @@ -25,7 +26,7 @@ namespace Umbraco.Tests.Routing base.Compose(); Composition.RegisterUnique(_ => Mock.Of()); - Composition.Register(); + Composition.Services.AddTransient(); } void SetDomains1() diff --git a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs index 81fe22a698..4063568d47 100644 --- a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs +++ b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using Microsoft.Extensions.DependencyInjection; using Moq; using NUnit.Framework; using Microsoft.Extensions.Logging; @@ -27,7 +28,7 @@ namespace Umbraco.Tests.Routing { base.Compose(); Composition.RegisterUnique(_ => Mock.Of()); - Composition.Register(); + Composition.Services.AddTransient(); } [Test] diff --git a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs index ea111a1e29..c624a720e9 100644 --- a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs +++ b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Examine; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -17,6 +18,7 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Persistence; using Umbraco.Core.Runtime; +using Umbraco.Infrastructure.Composing; using Umbraco.Net; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Stubs; @@ -43,43 +45,6 @@ namespace Umbraco.Tests.Runtimes TestComponent.Reset(); } - [Test] - public void ComponentLifeCycle() - { - using (var app = new TestUmbracoApplication()) - { - app.HandleApplicationStart(app, new EventArgs()); - - var e = app.Runtime.State.BootFailedException; - var m = ""; - switch (e) - { - case null: - m = ""; - break; - case BootFailedException bfe when bfe.InnerException != null: - m = "BootFailed: " + bfe.InnerException.GetType() + " " + bfe.InnerException.Message + " " + bfe.InnerException.StackTrace; - break; - default: - m = e.GetType() + " " + e.Message + " " + e.StackTrace; - break; - } - - Assert.AreNotEqual(RuntimeLevel.BootFailed, app.Runtime.State.Level, m); - Assert.IsTrue(TestComposer.Ctored); - Assert.IsTrue(TestComposer.Composed); - Assert.IsTrue(TestComponent.Ctored); - Assert.IsNotNull(TestComponent.ProfilingLogger); - Assert.IsInstanceOf(TestComponent.ProfilingLogger); - - // note: components are NOT disposed after boot - - Assert.IsFalse(TestComponent.Terminated); - - app.HandleApplicationEnd(); - Assert.IsTrue(TestComponent.Terminated); - } - } // test application public class TestUmbracoApplication : UmbracoApplicationBase @@ -124,15 +89,15 @@ namespace Umbraco.Tests.Runtimes return mock.Object; } - public override IFactory Configure(IRegister container) + public override void Configure(IServiceCollection services) { + var container = ServiceCollectionRegistryAdapter.Wrap(services); container.Register(Lifetime.Singleton); container.Register(Lifetime.Singleton); container.Register(typeof(ILogger<>), typeof(Logger<>), Lifetime.Singleton); - var factory = base.Configure(container); - return factory; + base.Configure(services); } // runs with only one single component diff --git a/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs b/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs index ebfb9da8b3..e661aa0bfc 100644 --- a/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopeEventDispatcherTests.cs @@ -15,8 +15,10 @@ using Umbraco.Core.Models; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Scoping; using Umbraco.Core.Services; +using Umbraco.Infrastructure.Composing; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Entities; +using Umbraco.Web; using Current = Umbraco.Web.Composing.Current; namespace Umbraco.Tests.Scoping @@ -34,14 +36,14 @@ namespace Umbraco.Tests.Scoping DoThing2 = null; DoThing3 = null; - var register = TestHelper.GetRegister(); + var wrapper = (ServiceCollectionRegistryAdapter) TestHelper.GetRegister(); - var composition = new Composition(register, TestHelper.GetMockedTypeLoader(), Mock.Of(), Mock.Of(), TestHelper.IOHelper, AppCaches.NoCache); + var composition = new Composition(wrapper.Services, TestHelper.GetMockedTypeLoader(), Mock.Of(), Mock.Of(), TestHelper.IOHelper, AppCaches.NoCache); - _testObjects = new TestObjects(register); + _testObjects = new TestObjects(wrapper); var globalSettings = new GlobalSettings(); - composition.RegisterUnique(factory => new FileSystems(factory, factory.TryGetInstance>(), factory.TryGetInstance(), TestHelper.IOHelper, Microsoft.Extensions.Options.Options.Create(globalSettings), TestHelper.GetHostingEnvironment())); + composition.RegisterUnique(factory => new FileSystems(factory, factory.GetService>(), factory.GetService(), TestHelper.IOHelper, Microsoft.Extensions.Options.Options.Create(globalSettings), TestHelper.GetHostingEnvironment())); composition.WithCollectionBuilder(); Current.Reset(); diff --git a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs index 68e1c4a2e2..1aa3594a96 100644 --- a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs @@ -73,7 +73,7 @@ namespace Umbraco.Tests.Scoping var runtimeStateMock = new Mock(); runtimeStateMock.Setup(x => x.Level).Returns(() => RuntimeLevel.Run); - var contentTypeFactory = Factory.GetInstance(); + var contentTypeFactory = Factory.GetRequiredService(); var documentRepository = Mock.Of(); var mediaRepository = Mock.Of(); var memberRepository = Mock.Of(); @@ -98,7 +98,7 @@ namespace Umbraco.Tests.Scoping DefaultCultureAccessor, new DatabaseDataSource(Mock.Of>()), Microsoft.Extensions.Options.Options.Create(globalSettings ?? new GlobalSettings()), - Factory.GetInstance(), + Factory.GetRequiredService(), new NoopPublishedModelFactory(), new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider(ShortStringHelper) }), hostingEnvironment, diff --git a/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs b/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs index cac420d5e2..9f2a05fdca 100644 --- a/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedXmlTests.cs @@ -79,7 +79,7 @@ namespace Umbraco.Tests.Scoping // xmlStore.Xml - the actual main xml document // publishedContentCache.GetXml() - the captured xml - private static XmlStore XmlStore => (Current.Factory.GetInstance() as XmlPublishedSnapshotService).XmlStore; + private static XmlStore XmlStore => (Current.Factory.GetRequiredService() as XmlPublishedSnapshotService).XmlStore; private static XmlDocument XmlMaster => XmlStore.Xml; private static XmlDocument XmlInContext => ((PublishedContentCache) Umbraco.Web.Composing.Current.UmbracoContext.Content).GetXml(false); diff --git a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs index 3c3e14e2c4..02484f2f0a 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs @@ -11,7 +11,9 @@ using Umbraco.Core.Composing; using Umbraco.Core.Logging; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence; +using Umbraco.Infrastructure.Composing; using Umbraco.Persistance.SqlCe; +using Umbraco.Web; using Current = Umbraco.Web.Composing.Current; namespace Umbraco.Tests.TestHelpers @@ -35,7 +37,7 @@ namespace Umbraco.Tests.TestHelpers { Current.Reset(); - var container = TestHelper.GetRegister(); + var wrapper = (ServiceCollectionRegistryAdapter) TestHelper.GetRegister(); var ioHelper = TestHelper.IOHelper; var logger = new ProfilingLogger(Mock.Of(), Mock.Of()); @@ -46,7 +48,7 @@ namespace Umbraco.Tests.TestHelpers logger, false); - var composition = new Composition(container, typeLoader, Mock.Of(), Mock.Of(), TestHelper.IOHelper, AppCaches.NoCache); + var composition = new Composition(wrapper.Services, typeLoader, Mock.Of(), Mock.Of(), TestHelper.IOHelper, AppCaches.NoCache); composition.RegisterUnique(_ => Mock.Of()); composition.RegisterUnique(_ => NullLoggerFactory.Instance); @@ -64,8 +66,8 @@ namespace Umbraco.Tests.TestHelpers var pocoMappers = new NPoco.MapperCollection { new PocoMapper() }; var pocoDataFactory = new FluentPocoDataFactory((type, iPocoDataFactory) => new PocoDataBuilder(type, pocoMappers).Init()); var sqlSyntax = new SqlCeSyntaxProvider(); - SqlContext = new SqlContext(sqlSyntax, DatabaseType.SQLCe, pocoDataFactory, new Lazy(() => factory.GetInstance())); - Mappers = factory.GetInstance(); + SqlContext = new SqlContext(sqlSyntax, DatabaseType.SQLCe, pocoDataFactory, new Lazy(() => factory.GetRequiredService())); + Mappers = factory.GetRequiredService(); SetUp(); } diff --git a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs index 51836502fb..4a59229980 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs @@ -110,11 +110,11 @@ namespace Umbraco.Tests.TestHelpers Mock.Of>(), Mock.Of(), Mock.Of(), - container?.GetInstance() ?? Current.Factory.GetInstance(), - container?.GetInstance()?? Current.Factory.GetInstance(), - container?.GetInstance()?? Current.Factory.GetInstance(), - container?.GetInstance() ?? Current.Factory.GetInstance(), - container?.GetInstance() ?? Current.Factory.GetInstance() + container?.GetRequiredService() ?? Current.Factory.GetRequiredService(), + container?.GetRequiredService()?? Current.Factory.GetRequiredService(), + container?.GetRequiredService()?? Current.Factory.GetRequiredService(), + container?.GetRequiredService() ?? Current.Factory.GetRequiredService(), + container?.GetRequiredService() ?? Current.Factory.GetRequiredService() ); } } diff --git a/src/Umbraco.Tests/TestHelpers/Stubs/TestControllerFactory.cs b/src/Umbraco.Tests/TestHelpers/Stubs/TestControllerFactory.cs index d0348cf589..af4114672b 100644 --- a/src/Umbraco.Tests/TestHelpers/Stubs/TestControllerFactory.cs +++ b/src/Umbraco.Tests/TestHelpers/Stubs/TestControllerFactory.cs @@ -61,7 +61,7 @@ namespace Umbraco.Tests.TestHelpers.Stubs foreach (var parameter in allParams) { var found = possibleParams.SingleOrDefault(x => x.GetType() == parameter.ParameterType) - ?? Current.Factory.GetInstance(parameter.ParameterType); + ?? Current.Factory.GetRequiredService(parameter.ParameterType); if (found != null) args.Add(found); } if (args.Count == allParams.Length) diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs b/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs index 671af42ef0..70768e89f0 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs @@ -85,7 +85,7 @@ namespace Umbraco.Tests.TestHelpers private T MockService(IFactory container = null) where T : class { - return container?.TryGetInstance() ?? new Mock().Object; + return container?.GetService() ?? new Mock().Object; } /// diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects.cs b/src/Umbraco.Tests/TestHelpers/TestObjects.cs index 0b284b8f47..ccca89f096 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects.cs @@ -71,13 +71,13 @@ namespace Umbraco.Tests.TestHelpers private Lazy GetLazyService(IFactory container, Func ctor) where T : class { - return new Lazy(() => container?.TryGetInstance() ?? ctor(container)); + return new Lazy(() => container?.GetService() ?? ctor(container)); } private T GetRepo(IFactory container) where T : class, IRepository { - return container?.TryGetInstance() ?? Mock.Of(); + return container?.GetService() ?? Mock.Of(); } public IScopeProvider GetScopeProvider(ILoggerFactory loggerFactory, ITypeFinder typeFinder = null, FileSystems fileSystems = null, IUmbracoDatabaseFactory databaseFactory = null) @@ -92,7 +92,7 @@ namespace Umbraco.Tests.TestHelpers // var mappersBuilder = new MapperCollectionBuilder(Current.Container); // FIXME: // mappersBuilder.AddCore(); // var mappers = mappersBuilder.CreateCollection(); - var mappers = Current.Factory.GetInstance(); + var mappers = Current.Factory.GetRequiredService(); databaseFactory = new UmbracoDatabaseFactory( loggerFactory.CreateLogger(), loggerFactory, diff --git a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs index 7d565d70b2..d6ff5fcfbb 100644 --- a/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs +++ b/src/Umbraco.Tests/TestHelpers/TestWithDatabaseBase.cs @@ -4,6 +4,7 @@ using System.Data.SqlServerCe; using System.Threading; using System.Web.Routing; using System.Xml; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Moq; @@ -59,7 +60,7 @@ namespace Umbraco.Tests.TestHelpers internal ScopeProvider ScopeProvider => Current.ScopeProvider as ScopeProvider; - protected ISqlContext SqlContext => Factory.GetInstance(); + protected ISqlContext SqlContext => Factory.GetRequiredService(); public override void SetUp() { @@ -74,7 +75,7 @@ namespace Umbraco.Tests.TestHelpers { base.Compose(); - Composition.Register(); + Composition.Services.AddTransient(); Composition.Register(factory => PublishedSnapshotService); Composition.Register(factory => DefaultCultureAccessor); @@ -90,8 +91,8 @@ namespace Umbraco.Tests.TestHelpers if (Options.Database == UmbracoTestOptions.Database.None) return TestObjects.GetDatabaseFactoryMock(); - var lazyMappers = new Lazy(f.GetInstance); - var factory = new UmbracoDatabaseFactory(f.GetInstance>(), f.GetInstance(), GetDbConnectionString(), GetDbProviderName(), lazyMappers, TestHelper.DbProviderFactoryCreator); + var lazyMappers = new Lazy(f.GetRequiredService); + var factory = new UmbracoDatabaseFactory(f.GetRequiredService>(), f.GetRequiredService(), GetDbConnectionString(), GetDbProviderName(), lazyMappers, TestHelper.DbProviderFactoryCreator); factory.ResetForTests(); return factory; }); @@ -105,7 +106,7 @@ namespace Umbraco.Tests.TestHelpers public override void TearDown() { - var profilingLogger = Factory.TryGetInstance(); + var profilingLogger = Factory.GetService(); var timer = profilingLogger?.TraceDuration("teardown"); // FIXME: move that one up try { @@ -242,11 +243,11 @@ namespace Umbraco.Tests.TestHelpers var cache = NoAppCache.Instance; ContentTypesCache ??= new PublishedContentTypeCache( - Factory.GetInstance(), - Factory.GetInstance(), - Factory.GetInstance(), - Factory.GetInstance(), - Factory.GetInstance>()); + Factory.GetRequiredService(), + Factory.GetRequiredService(), + Factory.GetRequiredService(), + Factory.GetRequiredService(), + Factory.GetRequiredService>()); // testing=true so XmlStore will not use the file nor the database @@ -254,19 +255,19 @@ namespace Umbraco.Tests.TestHelpers var variationContextAccessor = new TestVariationContextAccessor(); var service = new XmlPublishedSnapshotService( ServiceContext, - Factory.GetInstance(), + Factory.GetRequiredService(), ScopeProvider, cache, publishedSnapshotAccessor, variationContextAccessor, - Factory.GetInstance(), - Factory.GetInstance(), Factory.GetInstance(), Factory.GetInstance(), + Factory.GetRequiredService(), + Factory.GetRequiredService(), Factory.GetRequiredService(), Factory.GetRequiredService(), DefaultCultureAccessor, - Factory.GetInstance(), + Factory.GetRequiredService(), globalSettings ?? TestObjects.GetGlobalSettings(), HostingEnvironment, HostingLifetime, ShortStringHelper, new SiteDomainHelper(), - Factory.GetInstance(), + Factory.GetRequiredService(), ContentTypesCache, null, true, Options.PublishedRepositoryEvents); diff --git a/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs b/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs index 017f7022e7..735811d355 100644 --- a/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs +++ b/src/Umbraco.Tests/Testing/TestingTests/MockTests.cs @@ -3,6 +3,7 @@ using System.Globalization; using System.Linq; using System.Web; using System.Web.Security; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; using Moq; using NUnit.Framework; @@ -66,7 +67,7 @@ namespace Umbraco.Tests.Testing.TestingTests Composition.Register(_ => Mock.Of()); Composition.Register(_ => Mock.Of()); Composition.Register(_ => AppCaches.Disabled); - Composition.Register(); + Composition.Services.AddTransient(); // ReSharper disable once UnusedVariable var helper = new UmbracoHelper(Mock.Of(), diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index 347545068c..5e15a58017 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -9,6 +9,7 @@ using System.Web.Routing; using System.Web.Security; using System.Xml.Linq; using Examine; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Moq; @@ -42,6 +43,7 @@ using Umbraco.Core.Serialization; using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; using Umbraco.Core.Strings; +using Umbraco.Infrastructure.Composing; using Umbraco.Net; using Umbraco.Tests.Common; using Umbraco.Tests.TestHelpers; @@ -119,43 +121,43 @@ namespace Umbraco.Tests.Testing private TypeLoader _featureTypeLoader; #region Accessors - protected ServiceContext ServiceContext => Factory.GetInstance(); + protected ServiceContext ServiceContext => Factory.GetRequiredService(); - protected ILoggerFactory LoggerFactory => Factory.GetInstance(); + protected ILoggerFactory LoggerFactory => Factory.GetRequiredService(); protected IJsonSerializer JsonNetSerializer { get; } = new JsonNetSerializer(); protected IIOHelper IOHelper { get; private set; } protected UriUtility UriUtility => new UriUtility(HostingEnvironment); - protected IPublishedUrlProvider PublishedUrlProvider => Factory.GetInstance(); - protected IDataTypeService DataTypeService => Factory.GetInstance(); - protected IPasswordHasher PasswordHasher => Factory.GetInstance(); - protected Lazy PropertyEditorCollection => new Lazy(() => Factory.GetInstance()); - protected ILocalizationService LocalizationService => Factory.GetInstance(); + protected IPublishedUrlProvider PublishedUrlProvider => Factory.GetRequiredService(); + protected IDataTypeService DataTypeService => Factory.GetRequiredService(); + protected IPasswordHasher PasswordHasher => Factory.GetRequiredService(); + protected Lazy PropertyEditorCollection => new Lazy(() => Factory.GetRequiredService()); + protected ILocalizationService LocalizationService => Factory.GetRequiredService(); protected ILocalizedTextService LocalizedTextService { get; private set; } - protected IShortStringHelper ShortStringHelper => Factory?.GetInstance() ?? TestHelper.ShortStringHelper; - protected IImageUrlGenerator ImageUrlGenerator => Factory.GetInstance(); - protected UploadAutoFillProperties UploadAutoFillProperties => Factory.GetInstance(); + protected IShortStringHelper ShortStringHelper => Factory?.GetRequiredService() ?? TestHelper.ShortStringHelper; + protected IImageUrlGenerator ImageUrlGenerator => Factory.GetRequiredService(); + protected UploadAutoFillProperties UploadAutoFillProperties => Factory.GetRequiredService(); protected IUmbracoVersion UmbracoVersion { get; private set; } protected ITypeFinder TypeFinder { get; private set; } - protected IProfiler Profiler => Factory.GetInstance(); + protected IProfiler Profiler => Factory.GetRequiredService(); - protected virtual IProfilingLogger ProfilingLogger => Factory.GetInstance(); + protected virtual IProfilingLogger ProfilingLogger => Factory.GetRequiredService(); protected IHostingEnvironment HostingEnvironment { get; } = new AspNetHostingEnvironment(Microsoft.Extensions.Options.Options.Create(new HostingSettings())); protected IApplicationShutdownRegistry HostingLifetime { get; } = new AspNetApplicationShutdownRegistry(); - protected IIpResolver IpResolver => Factory.GetInstance(); - protected IBackOfficeInfo BackOfficeInfo => Factory.GetInstance(); - protected AppCaches AppCaches => Factory.GetInstance(); + protected IIpResolver IpResolver => Factory.GetRequiredService(); + protected IBackOfficeInfo BackOfficeInfo => Factory.GetRequiredService(); + protected AppCaches AppCaches => Factory.GetRequiredService(); - protected virtual ISqlSyntaxProvider SqlSyntax => Factory.GetInstance(); + protected virtual ISqlSyntaxProvider SqlSyntax => Factory.GetRequiredService(); - protected IMapperCollection Mappers => Factory.GetInstance(); + protected IMapperCollection Mappers => Factory.GetRequiredService(); - protected UmbracoMapper Mapper => Factory.GetInstance(); - protected IHttpContextAccessor HttpContextAccessor => Factory.GetInstance(); + protected UmbracoMapper Mapper => Factory.GetRequiredService(); + protected IHttpContextAccessor HttpContextAccessor => Factory.GetRequiredService(); protected IRuntimeState RuntimeState => MockRuntimeState(RuntimeLevel.Run); private ILoggerFactory _loggerFactory; @@ -204,11 +206,16 @@ namespace Umbraco.Tests.Testing var register = TestHelper.GetRegister(); - - Composition = new Composition(register, typeLoader, proflogger, MockRuntimeState(RuntimeLevel.Run), TestHelper.IOHelper, AppCaches.NoCache); + Composition = new Composition( + (register as ServiceCollectionRegistryAdapter).Services, + typeLoader, + proflogger, + MockRuntimeState(RuntimeLevel.Run), + TestHelper.IOHelper, + AppCaches.NoCache + ); //TestHelper.GetConfigs().RegisterWith(register); - Composition.RegisterUnique(typeof(ILoggerFactory), loggerFactory); Composition.Register(typeof(ILogger<>), typeof(Logger<>)); Composition.Register(typeof(ILogger), msLogger); @@ -316,7 +323,7 @@ namespace Umbraco.Tests.Testing Composition.RegisterUnique(); Composition.RegisterUnique(); Composition.SetCultureDictionaryFactory(); - Composition.Register(f => f.GetInstance().CreateDictionary(), Lifetime.Singleton); + Composition.Register(f => f.GetRequiredService().CreateDictionary(), Lifetime.Singleton); // register back office sections in the order we want them rendered Composition.WithCollectionBuilder().Append() .Append() @@ -339,11 +346,11 @@ namespace Umbraco.Tests.Testing var webRoutingSettings = new WebRoutingSettings(); Composition.RegisterUnique(factory => new UrlProvider( - factory.GetInstance(), + factory.GetRequiredService(), Microsoft.Extensions.Options.Options.Create(webRoutingSettings), new UrlProviderCollection(Enumerable.Empty()), new MediaUrlProviderCollection(Enumerable.Empty()), - factory.GetInstance())); + factory.GetRequiredService())); @@ -356,7 +363,7 @@ namespace Umbraco.Tests.Testing runtimeStateMock.Setup(x => x.Level).Returns(RuntimeLevel.Run); Composition.RegisterUnique(f => runtimeStateMock.Object); Composition.Register(_ => Mock.Of()); - Composition.Register(); + Composition.Services.AddTransient(); // ah... Composition.WithCollectionBuilder(); @@ -485,16 +492,16 @@ namespace Umbraco.Tests.Testing LoggerFactory, globalSettings, connectionStrings, - new Lazy(f.GetInstance), + new Lazy(f.GetRequiredService), TestHelper.DbProviderFactoryCreator)); - Composition.RegisterUnique(f => f.TryGetInstance().SqlContext); + Composition.RegisterUnique(f => f.GetService().SqlContext); Composition.WithCollectionBuilder(); // empty Composition.RegisterUnique(factory - => TestObjects.GetScopeProvider(_loggerFactory, factory.TryGetInstance(), factory.TryGetInstance(), factory.TryGetInstance())); - Composition.RegisterUnique(factory => (IScopeAccessor) factory.GetInstance()); + => TestObjects.GetScopeProvider(_loggerFactory, factory.GetService(), factory.GetService(), factory.GetService())); + Composition.RegisterUnique(factory => (IScopeAccessor) factory.GetRequiredService()); Composition.ComposeServices(); @@ -560,7 +567,7 @@ namespace Umbraco.Tests.Testing // reset and dispose scopes // ensures we don't leak an opened database connection // which would lock eg SqlCe .sdf files - if (Factory?.TryGetInstance() is ScopeProvider scopeProvider) + if (Factory?.GetService() is ScopeProvider scopeProvider) { Scope scope; while ((scope = scopeProvider.AmbientScope) != null) diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs b/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs index 2e3419720a..7b04e38e45 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs @@ -30,7 +30,7 @@ namespace Umbraco.Tests.UmbracoExamine [Test] public void Index_Property_Data_With_Value_Indexer() { - var contentValueSetBuilder = IndexInitializer.GetContentValueSetBuilder(Factory.GetInstance(), ScopeProvider, false); + var contentValueSetBuilder = IndexInitializer.GetContentValueSetBuilder(Factory.GetRequiredService(), ScopeProvider, false); using (var luceneDir = new RandomIdRamDirectory()) using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, HostingEnvironment, RuntimeState, luceneDir, @@ -122,8 +122,8 @@ namespace Umbraco.Tests.UmbracoExamine [Test] public void Rebuild_Index() { - var contentRebuilder = IndexInitializer.GetContentIndexRebuilder(Factory.GetInstance(), IndexInitializer.GetMockContentService(), ScopeProvider, false); - var mediaRebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetInstance(), IndexInitializer.GetMockMediaService()); + var contentRebuilder = IndexInitializer.GetContentIndexRebuilder(Factory.GetRequiredService(), IndexInitializer.GetMockContentService(), ScopeProvider, false); + var mediaRebuilder = IndexInitializer.GetMediaIndexRebuilder(Factory.GetRequiredService(), IndexInitializer.GetMockMediaService()); using (var luceneDir = new RandomIdRamDirectory()) using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, HostingEnvironment, RuntimeState, luceneDir, @@ -150,7 +150,7 @@ namespace Umbraco.Tests.UmbracoExamine [Test] public void Index_Protected_Content_Not_Indexed() { - var rebuilder = IndexInitializer.GetContentIndexRebuilder(Factory.GetInstance(), IndexInitializer.GetMockContentService(), ScopeProvider, false); + var rebuilder = IndexInitializer.GetContentIndexRebuilder(Factory.GetRequiredService(), IndexInitializer.GetMockContentService(), ScopeProvider, false); using (var luceneDir = new RandomIdRamDirectory()) @@ -275,7 +275,7 @@ namespace Umbraco.Tests.UmbracoExamine [Test] public void Index_Reindex_Content() { - var rebuilder = IndexInitializer.GetContentIndexRebuilder(Factory.GetInstance(), IndexInitializer.GetMockContentService(), ScopeProvider, false); + var rebuilder = IndexInitializer.GetContentIndexRebuilder(Factory.GetRequiredService(), IndexInitializer.GetMockContentService(), ScopeProvider, false); using (var luceneDir = new RandomIdRamDirectory()) using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, HostingEnvironment, RuntimeState, luceneDir, validator: new ContentValueSetValidator(false))) @@ -316,7 +316,7 @@ namespace Umbraco.Tests.UmbracoExamine public void Index_Delete_Index_Item_Ensure_Heirarchy_Removed() { - var rebuilder = IndexInitializer.GetContentIndexRebuilder(Factory.GetInstance(), IndexInitializer.GetMockContentService(), ScopeProvider, false); + var rebuilder = IndexInitializer.GetContentIndexRebuilder(Factory.GetRequiredService(), IndexInitializer.GetMockContentService(), ScopeProvider, false); using (var luceneDir = new RandomIdRamDirectory()) using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, HostingEnvironment, RuntimeState, luceneDir)) diff --git a/src/Umbraco.Tests/UmbracoExamine/SearchTests.cs b/src/Umbraco.Tests/UmbracoExamine/SearchTests.cs index d30aec874e..6186e5f782 100644 --- a/src/Umbraco.Tests/UmbracoExamine/SearchTests.cs +++ b/src/Umbraco.Tests/UmbracoExamine/SearchTests.cs @@ -54,7 +54,7 @@ namespace Umbraco.Tests.UmbracoExamine == allRecs); - var propertyEditors = Factory.GetInstance(); + var propertyEditors = Factory.GetRequiredService(); var rebuilder = IndexInitializer.GetContentIndexRebuilder(propertyEditors, contentService, ScopeProvider, true); using (var luceneDir = new RandomIdRamDirectory()) diff --git a/src/Umbraco.Tests/Web/UmbracoHelperTests.cs b/src/Umbraco.Tests/Web/UmbracoHelperTests.cs index 34beee7499..66c9395c59 100644 --- a/src/Umbraco.Tests/Web/UmbracoHelperTests.cs +++ b/src/Umbraco.Tests/Web/UmbracoHelperTests.cs @@ -33,7 +33,7 @@ namespace Umbraco.Tests.Web var typeFinder = TestHelper.GetTypeFinder(); var ioHelper = TestHelper.IOHelper; container - .Setup(x => x.GetInstance(typeof(TypeLoader))) + .Setup(x => x.GetRequiredService(typeof(TypeLoader))) .Returns(new TypeLoader( typeFinder, NoAppCache.Instance, diff --git a/src/Umbraco.Web.BackOffice/Extensions/WebMappingProfiles.cs b/src/Umbraco.Web.BackOffice/Extensions/WebMappingProfiles.cs index 71d3481edf..bc72b1dd44 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/WebMappingProfiles.cs +++ b/src/Umbraco.Web.BackOffice/Extensions/WebMappingProfiles.cs @@ -1,4 +1,5 @@ -using Umbraco.Core; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Core; using Umbraco.Core.BackOffice; using Umbraco.Core.Composing; using Umbraco.Core.Mapping; @@ -15,7 +16,7 @@ namespace Umbraco.Extensions .Add() .Add(); - composition.Register(); + composition.Services.AddTransient(); return composition; } diff --git a/src/Umbraco.Web.BackOffice/Runtime/BackOfficeComposer.cs b/src/Umbraco.Web.BackOffice/Runtime/BackOfficeComposer.cs index ca854b6f65..d15d419089 100644 --- a/src/Umbraco.Web.BackOffice/Runtime/BackOfficeComposer.cs +++ b/src/Umbraco.Web.BackOffice/Runtime/BackOfficeComposer.cs @@ -1,4 +1,5 @@ using System.Linq; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Umbraco.Core; using Umbraco.Core.Composing; @@ -26,8 +27,8 @@ namespace Umbraco.Web.BackOffice.Runtime composition.RegisterUnique(); composition.RegisterUnique(); composition.RegisterUnique(); - composition.Register(Lifetime.Request); - composition.Register(Lifetime.Request); + composition.Services.AddScoped(); + composition.Services.AddScoped(); composition.RegisterUnique(); composition.RegisterUnique(); @@ -43,9 +44,9 @@ namespace Umbraco.Web.BackOffice.Runtime composition.RegisterUnique(factory => new PhysicalFileSystem( - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance>(), + factory.GetRequiredService(), + factory.GetRequiredService(), + factory.GetRequiredService>(), "~/")); composition.RegisterUnique(); diff --git a/src/Umbraco.Web.Common/Builder/UmbracoBuilderExtensions.cs b/src/Umbraco.Web.Common/Builder/UmbracoBuilderExtensions.cs index 2725e1b7a6..3a251fff9e 100644 --- a/src/Umbraco.Web.Common/Builder/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Web.Common/Builder/UmbracoBuilderExtensions.cs @@ -28,7 +28,7 @@ namespace Umbraco.Web.Common.Builder => builder.AddWith(nameof(WithConfiguration), () => builder.Services.AddUmbracoConfiguration(builder.Config)); public static IUmbracoBuilder WithCore(this IUmbracoBuilder builder) - => builder.AddWith(nameof(WithCore), () => builder.Services.AddUmbracoCore(builder.WebHostEnvironment, builder.Config, out _)); + => builder.AddWith(nameof(WithCore), () => builder.Services.AddUmbracoCore(builder.WebHostEnvironment, builder.Config)); public static IUmbracoBuilder WithMiniProfiler(this IUmbracoBuilder builder) => builder.AddWith(nameof(WithMiniProfiler), () => diff --git a/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs b/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs index ed0d350dc8..9688e5794a 100644 --- a/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/ApplicationBuilderExtensions.cs @@ -42,10 +42,6 @@ namespace Umbraco.Extensions if (!app.UmbracoCanBoot()) return app; var runtime = app.ApplicationServices.GetRequiredService(); - if (runtime is CoreRuntime coreRuntime) - { - coreRuntime.ReplaceFactory(app.ApplicationServices); - } // Register a listener for application shutdown in order to terminate the runtime var hostLifetime = app.ApplicationServices.GetRequiredService(); @@ -57,7 +53,7 @@ namespace Umbraco.Extensions LogContext.Push(threadAbortEnricher); // NOTE: We are not in a using clause because we are not removing it, it is on the global context // Start the runtime! - runtime.Start(); + runtime.Start(app.ApplicationServices); return app; } diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs index ebe792a8a1..e870bb177a 100644 --- a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs @@ -116,9 +116,8 @@ namespace Umbraco.Extensions Assembly entryAssembly, AppCaches appCaches, ILoggingConfiguration loggingConfiguration, - IConfiguration configuration, - out IFactory factory) - => services.AddUmbracoCore(webHostEnvironment, umbContainer, entryAssembly, appCaches, loggingConfiguration, configuration, GetCoreRuntime, out factory); + IConfiguration configuration) + => services.AddUmbracoCore(webHostEnvironment, umbContainer, entryAssembly, appCaches, loggingConfiguration, configuration, GetCoreRuntime); /// /// Adds the Umbraco Configuration requirements @@ -160,18 +159,6 @@ namespace Umbraco.Extensions return services; } - /// - /// Adds the Umbraco Back Core requirements - /// - /// - /// - /// - /// - public static IServiceCollection AddUmbracoCore(this IServiceCollection services, IWebHostEnvironment webHostEnvironment, IConfiguration configuration) - { - return services.AddUmbracoCore(webHostEnvironment, configuration, out _); - } - /// /// Adds the Umbraco Back Core requirements /// @@ -180,7 +167,7 @@ namespace Umbraco.Extensions /// /// /// - public static IServiceCollection AddUmbracoCore(this IServiceCollection services, IWebHostEnvironment webHostEnvironment, IConfiguration configuration, out IFactory factory) + public static IServiceCollection AddUmbracoCore(this IServiceCollection services, IWebHostEnvironment webHostEnvironment, IConfiguration configuration) { var loggingConfig = new LoggingConfiguration( @@ -209,8 +196,7 @@ namespace Umbraco.Extensions appCaches, loggingConfig, configuration, - GetCoreRuntime, - out factory); + GetCoreRuntime); return services; } @@ -237,8 +223,7 @@ namespace Umbraco.Extensions ILoggingConfiguration loggingConfiguration, IConfiguration configuration, //TODO: Yep that's extremely ugly - Func getRuntime, - out IFactory factory) + Func getRuntime) { if (services is null) throw new ArgumentNullException(nameof(services)); var container = umbContainer; @@ -306,7 +291,7 @@ namespace Umbraco.Extensions appCaches, dbProviderFactoryCreator); - factory = coreRuntime.Configure(container); + coreRuntime.Configure(services); return services; } diff --git a/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs b/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs index 8f890c4259..cb247cff60 100644 --- a/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs +++ b/src/Umbraco.Web.Common/Runtime/AspNetCoreComposer.cs @@ -1,5 +1,6 @@ using System.Linq; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Umbraco.Core; using Umbraco.Core.Composing; @@ -60,7 +61,7 @@ namespace Umbraco.Web.Common.Runtime composition.RegisterUnique(); - composition.Register(); + composition.Services.AddTransient(); composition.RegisterUnique(); composition.RegisterMultipleUnique(); diff --git a/src/Umbraco.Web.Common/RuntimeMinification/SmidgeComposer.cs b/src/Umbraco.Web.Common/RuntimeMinification/SmidgeComposer.cs index 0cb7bc71d2..3ceba06c62 100644 --- a/src/Umbraco.Web.Common/RuntimeMinification/SmidgeComposer.cs +++ b/src/Umbraco.Web.Common/RuntimeMinification/SmidgeComposer.cs @@ -1,4 +1,5 @@ -using Smidge.FileProcessors; +using Microsoft.Extensions.DependencyInjection; +using Smidge.FileProcessors; using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Runtime; @@ -17,7 +18,7 @@ namespace Umbraco.Web.Common.RuntimeMinification composition.RegisterUnique(); composition.RegisterUnique(); - composition.Register(); + composition.Services.AddTransient(); } } } diff --git a/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Rte.cshtml b/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Rte.cshtml index b8c95400b2..0aef9d10ca 100644 --- a/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Rte.cshtml +++ b/src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Rte.cshtml @@ -2,9 +2,9 @@ @using Umbraco.Web.Composing @using Umbraco.Web.Templates @{ - var htmlLocalLinkParser = Current.Factory.GetInstance(); - var htmlUrlParser = Current.Factory.GetInstance(); - var htmlImageSourceParser = Current.Factory.GetInstance(); + var htmlLocalLinkParser = Current.Factory.GetRequiredService(); + var htmlUrlParser = Current.Factory.GetRequiredService(); + var htmlImageSourceParser = Current.Factory.GetRequiredService(); var value = htmlUrlParser.EnsureUrls(Model.value.ToString()); value = htmlImageSourceParser.EnsureImageSources(value); diff --git a/src/Umbraco.Web/Composing/Current.cs b/src/Umbraco.Web/Composing/Current.cs index 5a190a90a5..0fd7a02444 100644 --- a/src/Umbraco.Web/Composing/Current.cs +++ b/src/Umbraco.Web/Composing/Current.cs @@ -106,7 +106,7 @@ namespace Umbraco.Web.Composing get { if (_umbracoContextAccessor != null) return _umbracoContextAccessor; - return _umbracoContextAccessor = Factory.GetInstance(); + return _umbracoContextAccessor = Factory.GetRequiredService(); } set => _umbracoContextAccessor = value; // for tests } @@ -119,65 +119,65 @@ namespace Umbraco.Web.Composing => UmbracoContextAccessor.UmbracoContext; public static UmbracoHelper UmbracoHelper - => Factory.GetInstance(); + => Factory.GetRequiredService(); public static IUmbracoComponentRenderer UmbracoComponentRenderer - => Factory.GetInstance(); + => Factory.GetRequiredService(); public static ITagQuery TagQuery - => Factory.GetInstance(); + => Factory.GetRequiredService(); public static IRuntimeMinifier RuntimeMinifier - => Factory.GetInstance(); + => Factory.GetRequiredService(); public static DistributedCache DistributedCache - => Factory.GetInstance(); + => Factory.GetRequiredService(); public static IPublishedSnapshot PublishedSnapshot - => Factory.GetInstance().PublishedSnapshot; + => Factory.GetRequiredService().PublishedSnapshot; public static EventMessages EventMessages - => Factory.GetInstance().GetOrDefault(); + => Factory.GetRequiredService().GetOrDefault(); public static UrlProviderCollection UrlProviders - => Factory.GetInstance(); + => Factory.GetRequiredService(); public static MediaUrlProviderCollection MediaUrlProviders - => Factory.GetInstance(); + => Factory.GetRequiredService(); public static HealthCheckCollectionBuilder HealthCheckCollectionBuilder - => Factory.GetInstance(); + => Factory.GetRequiredService(); internal static ActionCollectionBuilder ActionCollectionBuilder - => Factory.GetInstance(); + => Factory.GetRequiredService(); public static ActionCollection Actions - => Factory.GetInstance(); + => Factory.GetRequiredService(); public static ContentFinderCollection ContentFinders - => Factory.GetInstance(); + => Factory.GetRequiredService(); public static IContentLastChanceFinder LastChanceContentFinder - => Factory.GetInstance(); + => Factory.GetRequiredService(); internal static EditorValidatorCollection EditorValidators - => Factory.GetInstance(); + => Factory.GetRequiredService(); internal static UmbracoApiControllerTypeCollection UmbracoApiControllerTypes - => Factory.GetInstance(); + => Factory.GetRequiredService(); internal static SurfaceControllerTypeCollection SurfaceControllerTypes - => Factory.GetInstance(); + => Factory.GetRequiredService(); internal static IPublishedSnapshotService PublishedSnapshotService - => Factory.GetInstance(); + => Factory.GetRequiredService(); public static ITreeService TreeService - => Factory.GetInstance(); + => Factory.GetRequiredService(); public static ISectionService SectionService - => Factory.GetInstance(); + => Factory.GetRequiredService(); public static IIconService IconService - => Factory.GetInstance(); + => Factory.GetRequiredService(); #endregion @@ -207,49 +207,49 @@ namespace Umbraco.Web.Composing // proxy Core for convenience - public static IMediaFileSystem MediaFileSystem => Factory.GetInstance(); + public static IMediaFileSystem MediaFileSystem => Factory.GetRequiredService(); - public static UmbracoMapper Mapper => Factory.GetInstance(); + public static UmbracoMapper Mapper => Factory.GetRequiredService(); - public static IRuntimeState RuntimeState => Factory.GetInstance(); + public static IRuntimeState RuntimeState => Factory.GetRequiredService(); - public static CacheRefresherCollection CacheRefreshers => Factory.GetInstance(); + public static CacheRefresherCollection CacheRefreshers => Factory.GetRequiredService(); - internal static IPublishedModelFactory PublishedModelFactory => Factory.GetInstance(); + internal static IPublishedModelFactory PublishedModelFactory => Factory.GetRequiredService(); - public static IServerMessenger ServerMessenger => Factory.GetInstance(); + public static IServerMessenger ServerMessenger => Factory.GetRequiredService(); - public static ILogger Logger => Factory.GetInstance>(); + public static ILogger Logger => Factory.GetRequiredService>(); - public static ILoggerFactory LoggerFactory => Factory.GetInstance(); + public static ILoggerFactory LoggerFactory => Factory.GetRequiredService(); - public static IProfiler Profiler => Factory.GetInstance(); + public static IProfiler Profiler => Factory.GetRequiredService(); - public static IProfilerHtml ProfilerHtml => Factory.GetInstance(); + public static IProfilerHtml ProfilerHtml => Factory.GetRequiredService(); - public static IProfilingLogger ProfilingLogger => Factory.GetInstance(); + public static IProfilingLogger ProfilingLogger => Factory.GetRequiredService(); - public static AppCaches AppCaches => Factory.GetInstance(); + public static AppCaches AppCaches => Factory.GetRequiredService(); - public static ServiceContext Services => Factory.GetInstance(); + public static ServiceContext Services => Factory.GetRequiredService(); - public static IScopeProvider ScopeProvider => Factory.GetInstance(); + public static IScopeProvider ScopeProvider => Factory.GetRequiredService(); - public static IPublishedContentTypeFactory PublishedContentTypeFactory => Factory.GetInstance(); + public static IPublishedContentTypeFactory PublishedContentTypeFactory => Factory.GetRequiredService(); - public static IPublishedValueFallback PublishedValueFallback => Factory.GetInstance(); + public static IPublishedValueFallback PublishedValueFallback => Factory.GetRequiredService(); - public static IVariationContextAccessor VariationContextAccessor => Factory.GetInstance(); + public static IVariationContextAccessor VariationContextAccessor => Factory.GetRequiredService(); - public static IIOHelper IOHelper => Factory.GetInstance(); - public static IHostingEnvironment HostingEnvironment => Factory.GetInstance(); - public static IIpResolver IpResolver => Factory.GetInstance(); - public static IUmbracoVersion UmbracoVersion => Factory.GetInstance(); - public static IPublishedUrlProvider PublishedUrlProvider => Factory.GetInstance(); - public static IMenuItemCollectionFactory MenuItemCollectionFactory => Factory.GetInstance(); - public static MembershipHelper MembershipHelper => Factory.GetInstance(); - public static IUmbracoApplicationLifetime UmbracoApplicationLifetime => Factory.GetInstance(); - public static IPublishedContentQuery PublishedContentQuery => Factory.GetInstance(); + public static IIOHelper IOHelper => Factory.GetRequiredService(); + public static IHostingEnvironment HostingEnvironment => Factory.GetRequiredService(); + public static IIpResolver IpResolver => Factory.GetRequiredService(); + public static IUmbracoVersion UmbracoVersion => Factory.GetRequiredService(); + public static IPublishedUrlProvider PublishedUrlProvider => Factory.GetRequiredService(); + public static IMenuItemCollectionFactory MenuItemCollectionFactory => Factory.GetRequiredService(); + public static MembershipHelper MembershipHelper => Factory.GetRequiredService(); + public static IUmbracoApplicationLifetime UmbracoApplicationLifetime => Factory.GetRequiredService(); + public static IPublishedContentQuery PublishedContentQuery => Factory.GetRequiredService(); #endregion } diff --git a/src/Umbraco.Web/Composing/ModuleInjector.cs b/src/Umbraco.Web/Composing/ModuleInjector.cs index 57ef766dea..e21b585ab7 100644 --- a/src/Umbraco.Web/Composing/ModuleInjector.cs +++ b/src/Umbraco.Web/Composing/ModuleInjector.cs @@ -20,7 +20,7 @@ namespace Umbraco.Web.Composing try { // using the service locator here - no other way, really - Module = Current.Factory.GetInstance(); + Module = Current.Factory.GetRequiredService(); } catch { @@ -30,7 +30,7 @@ namespace Umbraco.Web.Composing try { - runtimeState = Current.Factory.GetInstance(); + runtimeState = Current.Factory.GetRequiredService(); } catch { /* don't make it worse */ } diff --git a/src/Umbraco.Web/CompositionExtensions.cs b/src/Umbraco.Web/CompositionExtensions.cs index 906c8fb60d..add809c79f 100644 --- a/src/Umbraco.Web/CompositionExtensions.cs +++ b/src/Umbraco.Web/CompositionExtensions.cs @@ -1,6 +1,8 @@ using System; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Core; using Umbraco.Core.Composing; +using Umbraco.Infrastructure.Composing; using Umbraco.Web.Actions; using Umbraco.Web.ContentApps; using Umbraco.Web.Dashboards; @@ -28,7 +30,11 @@ namespace Umbraco.Web /// public static class WebCompositionExtensions { - + public static IFactory CreateFactory(this Composition composition) + { + composition.RegisterBuilders(); + return ServiceProviderFactoryAdapter.Wrap(composition.Services.BuildServiceProvider()); + } #region Uniques @@ -94,31 +100,6 @@ namespace Umbraco.Web composition.RegisterUnique(_ => helper); } - /// - /// Sets the default controller for rendering template views. - /// - /// The type of the controller. - /// The composition. - /// The controller type is registered to the container by the composition. - public static void SetDefaultRenderMvcController(this Composition composition) - => composition.SetDefaultRenderMvcController(typeof(TController)); - - /// - /// Sets the default controller for rendering template views. - /// - /// The composition. - /// The type of the controller. - /// The controller type is registered to the container by the composition. - public static void SetDefaultRenderMvcController(this Composition composition, Type controllerType) - { - composition.OnCreatingFactory["Umbraco.Core.DefaultRenderMvcController"] = () => - { - // no need to register: all IRenderMvcController are registered - //composition.Register(controllerType, Lifetime.Request); - Current.DefaultRenderMvcControllerType = controllerType; - }; - } - #endregion } } diff --git a/src/Umbraco.Web/Mvc/EnsurePublishedContentRequestAttribute.cs b/src/Umbraco.Web/Mvc/EnsurePublishedContentRequestAttribute.cs index feeec0a1ba..e9d39849eb 100644 --- a/src/Umbraco.Web/Mvc/EnsurePublishedContentRequestAttribute.cs +++ b/src/Umbraco.Web/Mvc/EnsurePublishedContentRequestAttribute.cs @@ -72,9 +72,9 @@ namespace Umbraco.Web.Mvc protected IUmbracoContext UmbracoContext => _umbracoContextAccessor?.UmbracoContext ?? Current.UmbracoContext; // TODO: try lazy property injection? - private IPublishedRouter PublishedRouter => Current.Factory.GetInstance(); + private IPublishedRouter PublishedRouter => Current.Factory.GetRequiredService(); - private IPublishedContentQuery PublishedContentQuery => _publishedContentQuery ?? (_publishedContentQuery = Current.Factory.GetInstance()); + private IPublishedContentQuery PublishedContentQuery => _publishedContentQuery ?? (_publishedContentQuery = Current.Factory.GetRequiredService()); public override void OnActionExecuted(ActionExecutedContext filterContext) { diff --git a/src/Umbraco.Web/Mvc/PluginController.cs b/src/Umbraco.Web/Mvc/PluginController.cs index 09ed97171e..4490c8dda5 100644 --- a/src/Umbraco.Web/Mvc/PluginController.cs +++ b/src/Umbraco.Web/Mvc/PluginController.cs @@ -66,11 +66,11 @@ namespace Umbraco.Web.Mvc protected PluginController() : this( - Current.Factory.GetInstance(), - Current.Factory.GetInstance(), - Current.Factory.GetInstance(), - Current.Factory.GetInstance(), - Current.Factory.GetInstance() + Current.Factory.GetRequiredService(), + Current.Factory.GetRequiredService(), + Current.Factory.GetRequiredService(), + Current.Factory.GetRequiredService(), + Current.Factory.GetRequiredService() ) { } diff --git a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs index af896ae243..7ba870553b 100644 --- a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs @@ -47,7 +47,7 @@ namespace Umbraco.Web.Mvc private IUmbracoContext UmbracoContext => _umbracoContext ?? _umbracoContextAccessor.UmbracoContext; - private UmbracoFeatures Features => Current.Factory.GetInstance(); // TODO: inject + private UmbracoFeatures Features => Current.Factory.GetRequiredService(); // TODO: inject #region IRouteHandler Members diff --git a/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs b/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs index 7eff581bab..43c3102a62 100644 --- a/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs +++ b/src/Umbraco.Web/Mvc/UmbracoViewPageOfTModel.cs @@ -105,10 +105,10 @@ namespace Umbraco.Web.Mvc protected UmbracoViewPage() : this( - Current.Factory.GetInstance(), - Current.Factory.GetInstance(), - Current.Factory.GetInstance>(), - Current.Factory.GetInstance>() + Current.Factory.GetRequiredService(), + Current.Factory.GetRequiredService(), + Current.Factory.GetRequiredService>(), + Current.Factory.GetRequiredService>() ) { } diff --git a/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs b/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs index 56549073f4..38d89aef59 100644 --- a/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/UmbracoVirtualNodeRouteHandler.cs @@ -12,7 +12,7 @@ namespace Umbraco.Web.Mvc public abstract class UmbracoVirtualNodeRouteHandler : IRouteHandler { // TODO: try lazy property injection? - private IPublishedRouter PublishedRouter => Current.Factory.GetInstance(); + private IPublishedRouter PublishedRouter => Current.Factory.GetRequiredService(); /// /// Returns the UmbracoContext for this route handler diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index 487212840b..5891f3abb4 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -27,9 +27,9 @@ namespace Umbraco.Web private static IPublishedValueFallback PublishedValueFallback => Current.PublishedValueFallback; private static IPublishedSnapshot PublishedSnapshot => Current.PublishedSnapshot; private static IUmbracoContext UmbracoContext => Current.UmbracoContext; - private static ISiteDomainHelper SiteDomainHelper => Current.Factory.GetInstance(); + private static ISiteDomainHelper SiteDomainHelper => Current.Factory.GetRequiredService(); private static IVariationContextAccessor VariationContextAccessor => Current.VariationContextAccessor; - private static IExamineManager ExamineManager => Current.Factory.GetInstance(); + private static IExamineManager ExamineManager => Current.Factory.GetRequiredService(); private static IUserService UserService => Current.Services.UserService; diff --git a/src/Umbraco.Web/Runtime/WebInitialComposer.cs b/src/Umbraco.Web/Runtime/WebInitialComposer.cs index 8d3b416012..3cfe3f409a 100644 --- a/src/Umbraco.Web/Runtime/WebInitialComposer.cs +++ b/src/Umbraco.Web/Runtime/WebInitialComposer.cs @@ -1,6 +1,7 @@ using System.Web.Mvc; using System.Web.Security; using Microsoft.AspNet.SignalR; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Dictionary; @@ -26,14 +27,14 @@ namespace Umbraco.Web.Runtime { base.Compose(composition); - composition.Register(); + composition.Services.AddTransient(); // register membership stuff composition.Register(factory => MembershipProviderExtensions.GetMembersMembershipProvider()); - composition.Register(factory => Roles.Enabled ? Roles.Provider : new MembersRoleProvider(factory.GetInstance())); - composition.Register(Lifetime.Request); - composition.Register(factory => factory.GetInstance().PublishedSnapshot.Members); + composition.Register(factory => Roles.Enabled ? Roles.Provider : new MembersRoleProvider(factory.GetRequiredService())); + composition.Services.AddScoped(); + composition.Register(factory => factory.GetRequiredService().PublishedSnapshot.Members); composition.RegisterUnique(); composition.RegisterUnique(); @@ -44,9 +45,9 @@ namespace Umbraco.Web.Runtime if (composition.RuntimeState.Level == RuntimeLevel.Run) composition.Register(factory => { - var umbCtx = factory.GetInstance(); - return new UmbracoHelper(umbCtx.IsFrontEndUmbracoRequest ? umbCtx.PublishedRequest?.PublishedContent : null, factory.GetInstance(), - factory.GetInstance(), factory.GetInstance()); + var umbCtx = factory.GetRequiredService(); + return new UmbracoHelper(umbCtx.IsFrontEndUmbracoRequest ? umbCtx.PublishedRequest?.PublishedContent : null, factory.GetRequiredService(), + factory.GetRequiredService(), factory.GetRequiredService()); }); else composition.Register(_ => new UmbracoHelper()); @@ -56,10 +57,13 @@ namespace Umbraco.Web.Runtime // configure the container for web //composition.ConfigureForWeb(); - composition - // TODO: This will depend on if we use ServiceBasedControllerActivator - see notes in Startup.cs - //.ComposeUmbracoControllers(GetType().Assembly) - .SetDefaultRenderMvcController(); // default controller for template views + //composition + /* TODO: This will depend on if we use ServiceBasedControllerActivator - see notes in Startup.cs + * You will likely need to set DefaultRenderMvcControllerType on Umbraco.Web.Composing.Current + * which is what the extension method below did previously. + */ + //.ComposeUmbracoControllers(GetType().Assembly) + //.SetDefaultRenderMvcController(); // default controller for template views //we need to eagerly scan controller types since they will need to be routed composition.WithCollectionBuilder() diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index a2a15ada05..31202255dd 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -356,4 +356,4 @@ - + \ No newline at end of file diff --git a/src/Umbraco.Web/UmbracoApplicationBase.cs b/src/Umbraco.Web/UmbracoApplicationBase.cs index baeab5634c..8ca7aac038 100644 --- a/src/Umbraco.Web/UmbracoApplicationBase.cs +++ b/src/Umbraco.Web/UmbracoApplicationBase.cs @@ -7,6 +7,7 @@ using System.Web; using System.Web.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Serilog; @@ -21,6 +22,7 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Logging.Serilog; using Umbraco.Core.Logging.Serilog.Enrichers; +using Umbraco.Infrastructure.Composing; using Umbraco.Net; using Umbraco.Web.Hosting; using Umbraco.Web.Logging; @@ -145,7 +147,7 @@ namespace Umbraco.Web /// protected virtual IRegister GetRegister(GlobalSettings globalSettings) { - return RegisterFactory.Create(globalSettings); + return ServiceCollectionRegistryAdapter.Wrap(new ServiceCollection()); } // events - in the order they trigger @@ -193,14 +195,14 @@ namespace Umbraco.Web Umbraco.Composing.Current.Profiler, Umbraco.Composing.Current.HostingEnvironment, Umbraco.Composing.Current.BackOfficeInfo); - _factory = Current.Factory = _runtime.Configure(register); + //_factory = Current.Factory = _runtime.Configure(register); // now we can add our request based logging enrichers (globally, which is what we were doing in netframework before) - LogContext.Push(new HttpSessionIdEnricher(_factory.GetInstance())); - LogContext.Push(new HttpRequestNumberEnricher(_factory.GetInstance())); - LogContext.Push(new HttpRequestIdEnricher(_factory.GetInstance())); + LogContext.Push(new HttpSessionIdEnricher(_factory.GetRequiredService())); + LogContext.Push(new HttpRequestNumberEnricher(_factory.GetRequiredService())); + LogContext.Push(new HttpRequestIdEnricher(_factory.GetRequiredService())); - _runtime.Start(); + _runtime.Start(null); } // called by ASP.NET (auto event wireup) once per app domain diff --git a/src/Umbraco.Web/UmbracoDefaultOwinStartup.cs b/src/Umbraco.Web/UmbracoDefaultOwinStartup.cs index edd429946f..caa3f441df 100644 --- a/src/Umbraco.Web/UmbracoDefaultOwinStartup.cs +++ b/src/Umbraco.Web/UmbracoDefaultOwinStartup.cs @@ -30,9 +30,9 @@ namespace Umbraco.Web public class UmbracoDefaultOwinStartup { protected IUmbracoContextAccessor UmbracoContextAccessor => Current.UmbracoContextAccessor; - protected GlobalSettings GlobalSettings => Current.Factory.GetInstance(); - protected SecuritySettings SecuritySettings => Current.Factory.GetInstance>().Value; - protected IUserPasswordConfiguration UserPasswordConfig => Current.Factory.GetInstance(); + protected GlobalSettings GlobalSettings => Current.Factory.GetRequiredService(); + protected SecuritySettings SecuritySettings => Current.Factory.GetRequiredService>().Value; + protected IUserPasswordConfiguration UserPasswordConfig => Current.Factory.GetRequiredService(); protected IRuntimeState RuntimeState => Current.RuntimeState; protected ServiceContext Services => Current.Services; protected UmbracoMapper Mapper => Current.Mapper; diff --git a/src/Umbraco.Web/WebApi/Filters/FeatureAuthorizeAttribute.cs b/src/Umbraco.Web/WebApi/Filters/FeatureAuthorizeAttribute.cs index 0cf23a31ca..eb0c36e189 100644 --- a/src/Umbraco.Web/WebApi/Filters/FeatureAuthorizeAttribute.cs +++ b/src/Umbraco.Web/WebApi/Filters/FeatureAuthorizeAttribute.cs @@ -20,7 +20,7 @@ namespace Umbraco.Web.WebApi.Filters public FeatureAuthorizeAttribute() { // attributes have to use Current.Container - _features = Current.Factory?.TryGetInstance(); + _features = Current.Factory?.GetService(); } protected override bool IsAuthorized(HttpActionContext actionContext) diff --git a/src/Umbraco.Web/WebApi/HttpActionContextExtensions.cs b/src/Umbraco.Web/WebApi/HttpActionContextExtensions.cs index 9b337f57aa..ced67bc791 100644 --- a/src/Umbraco.Web/WebApi/HttpActionContextExtensions.cs +++ b/src/Umbraco.Web/WebApi/HttpActionContextExtensions.cs @@ -60,7 +60,7 @@ namespace Umbraco.Web.WebApi throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } - var ioHelper = Current.Factory.GetInstance(); + var ioHelper = Current.Factory.GetRequiredService(); var root = ioHelper.MapPath(rootVirtualPath); //ensure it exists Directory.CreateDirectory(root); diff --git a/src/Umbraco.Web/WebApi/UmbracoApiControllerBase.cs b/src/Umbraco.Web/WebApi/UmbracoApiControllerBase.cs index 3434d825fe..308358f4e8 100644 --- a/src/Umbraco.Web/WebApi/UmbracoApiControllerBase.cs +++ b/src/Umbraco.Web/WebApi/UmbracoApiControllerBase.cs @@ -39,15 +39,15 @@ namespace Umbraco.Web.WebApi /// Dependencies are obtained from the service locator. protected UmbracoApiControllerBase() : this( - Current.Factory.GetInstance(), - Current.Factory.GetInstance(), - Current.Factory.GetInstance(), - Current.Factory.GetInstance(), - Current.Factory.GetInstance(), - Current.Factory.GetInstance(), - Current.Factory.GetInstance(), - Current.Factory.GetInstance(), - Current.Factory.GetInstance() + Current.Factory.GetRequiredService(), + Current.Factory.GetRequiredService(), + Current.Factory.GetRequiredService(), + Current.Factory.GetRequiredService(), + Current.Factory.GetRequiredService(), + Current.Factory.GetRequiredService(), + Current.Factory.GetRequiredService(), + Current.Factory.GetRequiredService(), + Current.Factory.GetRequiredService() ) { }