@ -1,6 +1,6 @@
// This software is part of the Autofac IoC container
// Copyright © 2015 Autofac Contributors
// http s ://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 <see cref="ContainerBuilder"/> into which the registrations should be made.
/// </param>
/// <param name="services">
/// A container builder that can be used to create an <see cref="IServiceProvider" /> .
/// The set of service descriptors to register in the container .
/// </param>
public static void Populate (
this ContainerBuilder builder ,
IServiceCollection services )
this ContainerBuilder builder ,
IServiceCollection services )
{
Populate ( builder , services , null ) ;
}
/// <summary>
/// Populates the Autofac container builder with the set of registered service descriptors
/// and makes <see cref="IServiceProvider"/> and <see cref="IServiceScopeFactory"/>
/// available in the container. Using this overload is incompatible with the ASP.NET Core
/// support for <see cref="IServiceProviderFactory{TContainerBuilder}"/>.
/// </summary>
/// <param name="builder">
/// The <see cref="ContainerBuilder"/> into which the registrations should be made.
/// </param>
/// <param name="services">
/// A container builder that can be used to create an <see cref="IServiceProvider" />.
/// </param>
/// <param name="lifetimeScopeTagForSingletons">
/// If provided and not <see langword="null"/> then all registrations with lifetime <see cref="ServiceLifetime.Singleton" /> are registered
/// using <see cref="IRegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.InstancePerMatchingLifetimeScope" />
/// with provided <paramref name="lifetimeScopeTagForSingletons"/>
/// instead of using <see cref="IRegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.SingleInstance"/>.
/// </param>
/// <remarks>
/// <para>
/// Specifying a <paramref name="lifetimeScopeTagForSingletons"/> 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
/// <see cref="AutofacServiceProvider"/> using the child lifetime scope.
/// </para>
/// </remarks>
public static void Populate (
this ContainerBuilder builder ,
IServiceCollection services ,
object lifetimeScopeTagForSingletons )
{
if ( services = = null )
{
throw new ArgumentNullException ( nameof ( services ) ) ;
}
builder . RegisterType < AutofacServiceProvider > ( ) . As < IServiceProvider > ( ) ;
builder . RegisterType < AutofacServiceScopeFactory > ( ) . As < IServiceScopeFactory > ( ) ;
builder . RegisterType < AutofacServiceProvider > ( ) . As < IServiceProvider > ( ) . 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 < IServiceScopeFactory > ( ) ;
Register ( builder , services , lifetimeScopeTagForSingletons ) ;
Register ( builder , services ) ;
}
/// <summary>
@ -113,33 +64,18 @@ namespace Autofac.Extensions.DependencyInjection
/// <typeparam name="TRegistrationStyle">The object registration style.</typeparam>
/// <param name="registrationBuilder">The registration being built.</param>
/// <param name="lifecycleKind">The lifecycle specified on the service registration.</param>
/// <param name="lifetimeScopeTagForSingleton">
/// If not <see langword="null"/> then all registrations with lifetime <see cref="ServiceLifetime.Singleton" /> are registered
/// using <see cref="IRegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.InstancePerMatchingLifetimeScope" />
/// with provided <paramref name="lifetimeScopeTagForSingleton"/>
/// instead of using <see cref="IRegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.SingleInstance"/>.
/// </param>
/// <returns>
/// The <paramref name="registrationBuilder" />, configured with the proper lifetime scope,
/// and available for additional configuration.
/// </returns>
private static IRegistrationBuilder < object , TActivatorData , TRegistrationStyle > ConfigureLifecycle < TActivatorData , TRegistrationStyle > (
this IRegistrationBuilder < object , TActivatorData , TRegistrationStyle > registrationBuilder ,
ServiceLifetime lifecycleKind ,
object lifetimeScopeTagForSingleton )
this IRegistrationBuilder < object , TActivatorData , TRegistrationStyle > 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 <see cref="ContainerBuilder"/> into which the registrations should be made.
/// </param>
/// <param name="services">
/// A container builder that can be used to create an <see cref="IServiceProvider" />.
/// </param>
/// <param name="lifetimeScopeTagForSingletons">
/// If not <see langword="null"/> then all registrations with lifetime <see cref="ServiceLifetime.Singleton" /> are registered
/// using <see cref="IRegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.InstancePerMatchingLifetimeScope" />
/// with provided <paramref name="lifetimeScopeTagForSingletons"/>
/// instead of using <see cref="IRegistrationBuilder{TLimit,TActivatorData,TRegistrationStyle}.SingleInstance"/>.
/// The set of service descriptors to register in the container.
/// </param>
[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 < IModuleContainer > ( ) ;
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 < IServiceProvider > ( ) ;
return descriptor . ImplementationFactory ( serviceProvider ) ;
} )
. ConfigureLifecycle ( descriptor . Lifetime , lifetimeScopeTagForSingletons )
. CreateRegistration ( ) ;
//TODO: ConfigureAbpConventions ?
var registration = RegistrationBuilder . ForDelegate ( service . ServiceType , ( context , parameters ) = >
{
var serviceProvider = context . Resolve < IServiceProvider > ( ) ;
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 ) ;
}
}
}