diff --git a/Directory.Build.props b/Directory.Build.props index 94e58ab692..b11ffc52be 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -3,7 +3,7 @@ 5.0.0 - + 16.8.3 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 a51637e3e7..024fc3a258 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 -// https://autofac.org +// http://autofac.org // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation @@ -24,12 +24,9 @@ // 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; using Volo.Abp.Modularity; namespace Autofac.Extensions.DependencyInjection @@ -48,62 +45,16 @@ namespace Autofac.Extensions.DependencyInjection /// The into which the registrations should be made. /// /// - /// A container builder that can be used to create an . + /// The set of service descriptors to register in the container. /// public static void Populate( - this ContainerBuilder builder, - IServiceCollection services) + this ContainerBuilder builder, + IServiceCollection services) { - 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)); - } + builder.RegisterType().As(); + builder.RegisterType().As(); - 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); + Register(builder, services); } /// @@ -113,33 +64,18 @@ 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, - object lifetimeScopeTagForSingleton) + this IRegistrationBuilder registrationBuilder, + ServiceLifetime lifecycleKind) { switch (lifecycleKind) { case ServiceLifetime.Singleton: - if (lifetimeScopeTagForSingleton == null) - { - registrationBuilder.SingleInstance(); - } - else - { - registrationBuilder.InstancePerMatchingLifetimeScope(lifetimeScopeTagForSingleton); - } - + registrationBuilder.SingleInstance(); break; case ServiceLifetime.Scoped: registrationBuilder.InstancePerLifetimeScope(); @@ -159,65 +95,57 @@ namespace Autofac.Extensions.DependencyInjection /// The into which the registrations should be made. /// /// - /// 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 . + /// The set of service descriptors to register in the container. /// - [SuppressMessage("CA2000", "CA2000", Justification = "Registrations created here are disposed when the built container is disposed.")] private static void Register( - ContainerBuilder builder, - IServiceCollection services, - object lifetimeScopeTagForSingletons) + ContainerBuilder builder, + IServiceCollection services) { var moduleContainer = services.GetSingletonInstance(); var registrationActionList = services.GetRegistrationActionList(); - foreach (var descriptor in services) + foreach (var service in services) { - if (descriptor.ImplementationType != null) + if (service.ImplementationType != null) { // Test if the an open generic type is being registered - var serviceTypeInfo = descriptor.ServiceType.GetTypeInfo(); + var serviceTypeInfo = service.ServiceType.GetTypeInfo(); if (serviceTypeInfo.IsGenericTypeDefinition) { builder - .RegisterGeneric(descriptor.ImplementationType) - .As(descriptor.ServiceType) - .ConfigureLifecycle(descriptor.Lifetime, lifetimeScopeTagForSingletons) + .RegisterGeneric(service.ImplementationType) + .As(service.ServiceType) + .ConfigureLifecycle(service.Lifetime) .ConfigureAbpConventions(moduleContainer, registrationActionList); } else { builder - .RegisterType(descriptor.ImplementationType) - .As(descriptor.ServiceType) - .ConfigureLifecycle(descriptor.Lifetime, lifetimeScopeTagForSingletons) + .RegisterType(service.ImplementationType) + .As(service.ServiceType) + .ConfigureLifecycle(service.Lifetime) .ConfigureAbpConventions(moduleContainer, registrationActionList); } } - else if (descriptor.ImplementationFactory != null) + else if (service.ImplementationFactory != null) { - var registration = RegistrationBuilder.ForDelegate(descriptor.ServiceType, (context, parameters) => - { - var serviceProvider = context.Resolve(); - return descriptor.ImplementationFactory(serviceProvider); - }) - .ConfigureLifecycle(descriptor.Lifetime, lifetimeScopeTagForSingletons) - .CreateRegistration(); - //TODO: ConfigureAbpConventions ? + var registration = RegistrationBuilder.ForDelegate(service.ServiceType, (context, parameters) => + { + var serviceProvider = context.Resolve(); + return service.ImplementationFactory(serviceProvider); + }) + .ConfigureLifecycle(service.Lifetime) + .CreateRegistration(); + //TODO: ConfigureAbpConventions ? builder.RegisterComponent(registration); } else { builder - .RegisterInstance(descriptor.ImplementationInstance) - .As(descriptor.ServiceType) - .ConfigureLifecycle(descriptor.Lifetime, null); + .RegisterInstance(service.ImplementationInstance) + .As(service.ServiceType) + .ConfigureLifecycle(service.Lifetime); } } } diff --git a/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProvider.cs b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProvider.cs new file mode 100644 index 0000000000..1c1a24ff66 --- /dev/null +++ b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProvider.cs @@ -0,0 +1,122 @@ +// 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 new file mode 100644 index 0000000000..21a7ca331d --- /dev/null +++ b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceProviderFactory.cs @@ -0,0 +1,77 @@ +// 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 new file mode 100644 index 0000000000..425c6769da --- /dev/null +++ b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScope.cs @@ -0,0 +1,67 @@ +// 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 new file mode 100644 index 0000000000..31917fd079 --- /dev/null +++ b/framework/src/Volo.Abp.Autofac/Autofac/Extensions/DependencyInjection/AutofacServiceScopeFactory.cs @@ -0,0 +1,65 @@ +// 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 b33c9a3b66..ec9e4c0364 100644 --- a/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj +++ b/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj @@ -15,10 +15,8 @@ - - - +