Microsoft.Framework.DependencyInjection.Autofac源码分析
该工程只有一个代码静态类AutofacRegistration,但是该类有3个扩展方法,以及3个内部类。扩展方法如下:
public static class AutofacRegistration { public static void Populate(this ContainerBuilder builder,IEnumerable<ServiceDescriptor> descriptors); private static void Register(ContainerBuilder builder,IEnumerable<ServiceDescriptor> descriptors); private static IRegistrationBuilder<object, T, U> ConfigureLifecycle<T, U>(this IRegistrationBuilder<object, T, U> registrationBuilder,ServiceLifetime lifecycleKind) }
在Autofac中,ContainerBuilder是用于类型注册的,3个扩展方法都是基于此展开的。
Populate方法如下:先对IServiceProvider、IServiceScopeFactory接口进行注册,之后调用Register方法,对于外部的具体类型进行注册。该方法的入参是IEnumerable<ServiceDescriptor> descriptors类型,所以参数可以直接使用IServiceCollection(也就是List<ServiceDescriptor>)。
public static void Populate(this ContainerBuilder builder, IEnumerable<ServiceDescriptor> descriptors) { builder.RegisterType<AutofacServiceProvider>().As<IServiceProvider>(); builder.RegisterType<AutofacServiceScopeFactory>().As<IServiceScopeFactory>(); Register(builder, descriptors); }
对于Register方法相对复杂些,需要将ServiceDescriptor对象转化为实际的注册类型,代码如下所示:
private static void Register( ContainerBuilder builder, IEnumerable<ServiceDescriptor> descriptors) { foreach (var descriptor in descriptors) { if (descriptor.ImplementationType != null) { // Test if the an open generic type is being registered var serviceTypeInfo = descriptor.ServiceType.GetTypeInfo(); if (serviceTypeInfo.IsGenericTypeDefinition) { builder .RegisterGeneric(descriptor.ImplementationType) .As(descriptor.ServiceType) .ConfigureLifecycle(descriptor.Lifetime); } else { builder .RegisterType(descriptor.ImplementationType) .As(descriptor.ServiceType) .ConfigureLifecycle(descriptor.Lifetime); } } else if (descriptor.ImplementationFactory != null) { var registration = RegistrationBuilder.ForDelegate(descriptor.ServiceType, (context, parameters) => { var serviceProvider = context.Resolve<IServiceProvider>(); return descriptor.ImplementationFactory(serviceProvider); }) .ConfigureLifecycle(descriptor.Lifetime) .CreateRegistration(); builder.RegisterComponent(registration); } else { builder .RegisterInstance(descriptor.ImplementationInstance) .As(descriptor.ServiceType) .ConfigureLifecycle(descriptor.Lifetime); } } }