diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs index e0f7ec50ad..f1a6264683 100644 --- a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs +++ b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacRegistration.cs @@ -1,6 +1,6 @@ // This software is part of the Autofac IoC container // Copyright © 2015 Autofac Contributors -// http://autofac.org +// https://autofac.org // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -24,10 +24,13 @@ // OTHER DEALINGS IN THE SOFTWARE. using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using Autofac.Builder; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Autofac; +using Volo.Abp; using Volo.Abp.Modularity; namespace Autofac.Extensions.DependencyInjection @@ -46,16 +49,62 @@ namespace Autofac.Extensions.DependencyInjection /// The into which the registrations should be made. /// /// - /// The set of service descriptors to register in the container. + /// A container builder that can be used to create an . /// public static void Populate( - this ContainerBuilder builder, - IServiceCollection services) + this ContainerBuilder builder, + IServiceCollection services) { - builder.RegisterType().As(); - builder.RegisterType().As(); + Populate(builder, services, null); + } + + /// + /// Populates the Autofac container builder with the set of registered service descriptors + /// and makes and + /// available in the container. Using this overload is incompatible with the ASP.NET Core + /// support for . + /// + /// + /// The into which the registrations should be made. + /// + /// + /// A container builder that can be used to create an . + /// + /// + /// If provided and not then all registrations with lifetime are registered + /// using + /// with provided + /// instead of using . + /// + /// + /// + /// Specifying a addresses a specific case where you have + /// an application that uses Autofac but where you need to isolate a set of services in a child scope. For example, + /// if you have a large application that self-hosts ASP.NET Core items, you may want to isolate the ASP.NET + /// Core registrations in a child lifetime scope so they don't show up for the rest of the application. + /// This overload allows that. Note it is the developer's responsibility to execute this and create an + /// using the child lifetime scope. + /// + /// + public static void Populate( + this ContainerBuilder builder, + IServiceCollection services, + object lifetimeScopeTagForSingletons) + { + if (services == null) + { + throw new ArgumentNullException(nameof(services)); + } - Register(builder, services); + builder.RegisterType().As().ExternallyOwned(); + var autofacServiceScopeFactory = typeof(AutofacServiceProvider).Assembly.GetType("Autofac.Extensions.DependencyInjection.AutofacServiceScopeFactory"); + if (autofacServiceScopeFactory == null) + { + throw new AbpException("Unable get type of Autofac.Extensions.DependencyInjection.AutofacServiceScopeFactory!"); + } + builder.RegisterType(autofacServiceScopeFactory).As(); + + Register(builder, services, lifetimeScopeTagForSingletons); } /// @@ -65,18 +114,33 @@ namespace Autofac.Extensions.DependencyInjection /// The object registration style. /// The registration being built. /// The lifecycle specified on the service registration. + /// + /// If not then all registrations with lifetime are registered + /// using + /// with provided + /// instead of using . + /// /// /// The , configured with the proper lifetime scope, /// and available for additional configuration. /// private static IRegistrationBuilder ConfigureLifecycle( - this IRegistrationBuilder registrationBuilder, - ServiceLifetime lifecycleKind) + this IRegistrationBuilder registrationBuilder, + ServiceLifetime lifecycleKind, + object lifetimeScopeTagForSingleton) { switch (lifecycleKind) { case ServiceLifetime.Singleton: - registrationBuilder.SingleInstance(); + if (lifetimeScopeTagForSingleton == null) + { + registrationBuilder.SingleInstance(); + } + else + { + registrationBuilder.InstancePerMatchingLifetimeScope(lifetimeScopeTagForSingleton); + } + break; case ServiceLifetime.Scoped: registrationBuilder.InstancePerLifetimeScope(); @@ -96,59 +160,67 @@ namespace Autofac.Extensions.DependencyInjection /// The into which the registrations should be made. /// /// - /// The set of service descriptors to register in the container. + /// A container builder that can be used to create an . + /// + /// + /// If not then all registrations with lifetime are registered + /// using + /// with provided + /// instead of using . /// + [SuppressMessage("CA2000", "CA2000", Justification = "Registrations created here are disposed when the built container is disposed.")] private static void Register( - ContainerBuilder builder, - IServiceCollection services) + ContainerBuilder builder, + IServiceCollection services, + object lifetimeScopeTagForSingletons) { var moduleContainer = services.GetSingletonInstance(); var registrationActionList = services.GetRegistrationActionList(); - foreach (var service in services) + foreach (var descriptor in services) { - if (service.ImplementationType != null) + if (descriptor.ImplementationType != null) { // Test if the an open generic type is being registered - var serviceTypeInfo = service.ServiceType.GetTypeInfo(); + var serviceTypeInfo = descriptor.ServiceType.GetTypeInfo(); if (serviceTypeInfo.IsGenericTypeDefinition) { builder - .RegisterGeneric(service.ImplementationType) - .As(service.ServiceType) - .ConfigureLifecycle(service.Lifetime) + .RegisterGeneric(descriptor.ImplementationType) + .As(descriptor.ServiceType) + .ConfigureLifecycle(descriptor.Lifetime, lifetimeScopeTagForSingletons) .FindConstructorsWith(new AbpAutofacConstructorFinder()) .ConfigureAbpConventions(moduleContainer, registrationActionList); } else { builder - .RegisterType(service.ImplementationType) - .As(service.ServiceType) - .ConfigureLifecycle(service.Lifetime) + .RegisterType(descriptor.ImplementationType) + .As(descriptor.ServiceType) + .ConfigureLifecycle(descriptor.Lifetime, lifetimeScopeTagForSingletons) .FindConstructorsWith(new AbpAutofacConstructorFinder()) .ConfigureAbpConventions(moduleContainer, registrationActionList); } } - else if (service.ImplementationFactory != null) + else if (descriptor.ImplementationFactory != null) { - var registration = RegistrationBuilder.ForDelegate(service.ServiceType, (context, parameters) => - { - var serviceProvider = context.Resolve(); - return service.ImplementationFactory(serviceProvider); - }) - .ConfigureLifecycle(service.Lifetime) - .CreateRegistration(); - //TODO: ConfigureAbpConventions ? + var registration = RegistrationBuilder.ForDelegate(descriptor.ServiceType, (context, parameters) => + { + var serviceProvider = context.Resolve(); + return descriptor.ImplementationFactory(serviceProvider); + }) + .ConfigureLifecycle(descriptor.Lifetime, lifetimeScopeTagForSingletons) + .CreateRegistration(); + //TODO: ConfigureAbpConventions ? builder.RegisterComponent(registration); } else { builder - .RegisterInstance(service.ImplementationInstance) - .As(service.ServiceType) - .ConfigureLifecycle(service.Lifetime); + .RegisterInstance(descriptor.ImplementationInstance) + .As(descriptor.ServiceType) + .ConfigureLifecycle(descriptor.Lifetime, null); } } } diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProvider.cs b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProvider.cs deleted file mode 100644 index 1c1a24ff66..0000000000 --- a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProvider.cs +++ /dev/null @@ -1,122 +0,0 @@ -// This software is part of the Autofac IoC container -// Copyright © 2015 Autofac Contributors -// https://autofac.org -// -// 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. - -using System; -using Microsoft.Extensions.DependencyInjection; - -namespace Autofac.Extensions.DependencyInjection -{ - /// - /// Autofac implementation of the ASP.NET Core . - /// - /// - /// - public class AutofacServiceProvider : IServiceProvider, ISupportRequiredService, IDisposable - { - private readonly ILifetimeScope _lifetimeScope; - - private bool _disposed = false; - - /// - /// Initializes a new instance of the class. - /// - /// - /// The lifetime scope from which services will be resolved. - /// - public AutofacServiceProvider(ILifetimeScope lifetimeScope) - { - this._lifetimeScope = lifetimeScope; - } - - /// - /// Gets service of type from the - /// and requires it be present. - /// - /// - /// An object that specifies the type of service object to get. - /// - /// - /// A service object of type . - /// - /// - /// Thrown if the isn't registered with the container. - /// - /// - /// Thrown if the object can't be resolved from the container. - /// - public object GetRequiredService(Type serviceType) - { - return this._lifetimeScope.Resolve(serviceType); - } - - /// - /// Gets the service object of the specified type. - /// - /// - /// An object that specifies the type of service object to get. - /// - /// - /// A service object of type ; or - /// if there is no service object of type . - /// - public object GetService(Type serviceType) - { - return this._lifetimeScope.ResolveOptional(serviceType); - } - - /// - /// Gets the underlying instance of . - /// - public ILifetimeScope LifetimeScope => _lifetimeScope; - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// - /// to release both managed and unmanaged resources; - /// to release only unmanaged resources. - /// - protected virtual void Dispose(bool disposing) - { - if (!this._disposed) - { - this._disposed = true; - if (disposing) - { - this._lifetimeScope.Dispose(); - } - } - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - this.Dispose(true); - GC.SuppressFinalize(this); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProviderFactory.cs b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProviderFactory.cs deleted file mode 100644 index 21a7ca331d..0000000000 --- a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProviderFactory.cs +++ /dev/null @@ -1,77 +0,0 @@ -// This software is part of the Autofac IoC container -// Copyright © 2017 Autofac Contributors -// http://autofac.org -// -// 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. - -using System; -using Microsoft.Extensions.DependencyInjection; - -namespace Autofac.Extensions.DependencyInjection -{ - /// - /// A factory for creating a and an . - /// - public class AutofacServiceProviderFactory : IServiceProviderFactory - { - private readonly Action _configurationAction; - - /// - /// Initializes a new instance of the class. - /// - /// Action on a that adds component registrations to the container. - public AutofacServiceProviderFactory(Action configurationAction = null) - { - _configurationAction = configurationAction ?? (builder => { }); - } - - /// - /// Creates a container builder from an . - /// - /// The collection of services - /// A container builder that can be used to create an . - public ContainerBuilder CreateBuilder(IServiceCollection services) - { - var builder = new ContainerBuilder(); - - builder.Populate(services); - - _configurationAction(builder); - - return builder; - } - - /// - /// Creates an from the container builder. - /// - /// The container builder - /// An - public IServiceProvider CreateServiceProvider(ContainerBuilder containerBuilder) - { - if (containerBuilder == null) throw new ArgumentNullException(nameof(containerBuilder)); - - var container = containerBuilder.Build(); - - return new AutofacServiceProvider(container); - } - } -} diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScope.cs b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScope.cs deleted file mode 100644 index 425c6769da..0000000000 --- a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScope.cs +++ /dev/null @@ -1,67 +0,0 @@ -// This software is part of the Autofac IoC container -// Copyright © 2015 Autofac Contributors -// http://autofac.org -// -// 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. - -using System; -using Microsoft.Extensions.DependencyInjection; - -namespace Autofac.Extensions.DependencyInjection -{ - /// - /// Autofac implementation of the ASP.NET Core . - /// - /// - internal class AutofacServiceScope : IServiceScope - { - private readonly ILifetimeScope _lifetimeScope; - - /// - /// Initializes a new instance of the class. - /// - /// - /// The lifetime scope from which services should be resolved for this service scope. - /// - public AutofacServiceScope(ILifetimeScope lifetimeScope) - { - this._lifetimeScope = lifetimeScope; - this.ServiceProvider = this._lifetimeScope.Resolve(); - } - - /// - /// Gets an corresponding to this service scope. - /// - /// - /// An that can be used to resolve dependencies from the scope. - /// - public IServiceProvider ServiceProvider { get; } - - /// - /// Disposes of the lifetime scope and resolved disposable services. - /// - public void Dispose() - { - this._lifetimeScope.Dispose(); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScopeFactory.cs b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScopeFactory.cs deleted file mode 100644 index 31917fd079..0000000000 --- a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScopeFactory.cs +++ /dev/null @@ -1,65 +0,0 @@ -// This software is part of the Autofac IoC container -// Copyright © 2015 Autofac Contributors -// http://autofac.org -// -// 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. - -using System.Diagnostics.CodeAnalysis; -using Microsoft.Extensions.DependencyInjection; - -namespace Autofac.Extensions.DependencyInjection -{ - /// - /// Autofac implementation of the ASP.NET Core . - /// - /// - [SuppressMessage("Microsoft.ApiDesignGuidelines", "CA2213", Justification = "The creator of the root service lifetime scope is responsible for disposal.")] - internal class AutofacServiceScopeFactory : IServiceScopeFactory - { - private readonly ILifetimeScope _lifetimeScope; - - /// - /// Initializes a new instance of the class. - /// - /// The lifetime scope. - public AutofacServiceScopeFactory(ILifetimeScope lifetimeScope) - { - this._lifetimeScope = lifetimeScope; - } - - /// - /// Creates an which contains an - /// used to resolve dependencies within - /// the scope. - /// - /// - /// An controlling the lifetime of the scope. Once - /// this is disposed, any scoped services that have been resolved - /// from the - /// will also be disposed. - /// - public IServiceScope CreateScope() - { - return new AutofacServiceScope(this._lifetimeScope.BeginLifetimeScope()); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj b/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj index ec9e4c0364..a57ac74e62 100644 --- a/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj +++ b/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj @@ -15,8 +15,10 @@ - + + +