[Asp.net 5] DependencyInjection项目代码分析2
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); } } }
代码看起来挺多,实际也很简单对于列表进行循环遍历,对于每一项:如果注册类型不为空,使用ContainerBuilder的类型注册方法进行注册(包括泛型和非泛型的);如果类型没提供,判断是否为类型提供工厂delegate,如果提供,使用ContainerBuilder注册代理的方式注册;最后都没有直接将实例类型进行注册。在ContainerBuilder中涉及到了ConfigureLifecycle方法,世界该方法仅仅是将DependencyInjection中定义的ServiceLifetime枚举转化为Autofac能够识别的类型。
private static IRegistrationBuilder<object, T, U> ConfigureLifecycle<T, U>( this IRegistrationBuilder<object, T, U> registrationBuilder, ServiceLifetime lifecycleKind) { switch (lifecycleKind) { case ServiceLifetime.Singleton: registrationBuilder.SingleInstance(); break; case ServiceLifetime.Scoped: registrationBuilder.InstancePerLifetimeScope(); break; case ServiceLifetime.Transient: registrationBuilder.InstancePerDependency(); break; } return registrationBuilder; }
*IRegistrationBuilder是Autofac中对于注入类型范围进行控制的接口
回过头来我们看下AutofacServiceProvider和AutofacServiceScopeFactory类(Populate方法进行的注入实现类)。
AutofacServiceScopeFactory类,实现IServiceScopeFactory接口,并且CreateScope方法创建一个新AutofacServiceScope实例
private class AutofacServiceScopeFactory : IServiceScopeFactory { private readonly ILifetimeScope _lifetimeScope; public AutofacServiceScopeFactory(ILifetimeScope lifetimeScope) { _lifetimeScope = lifetimeScope; } public IServiceScope CreateScope() { return new AutofacServiceScope(_lifetimeScope.BeginLifetimeScope()); } }
AutofacServiceScope类。使用内部ILifetimeScope创建新的IServiceProvider对象。当当前作用域失效时,调用Dispose方法,以释放内部的IServiceProvider对象,保证不同的ILifetimeScope(Scope)的IServiceProvider生成的对象不同。
private class AutofacServiceScope : IServiceScope { private readonly ILifetimeScope _lifetimeScope; private readonly IServiceProvider _serviceProvider; public AutofacServiceScope(ILifetimeScope lifetimeScope) { _lifetimeScope = lifetimeScope; _serviceProvider = _lifetimeScope.Resolve<IServiceProvider>(); } public IServiceProvider ServiceProvider { get { return _serviceProvider; } } public void Dispose() { _lifetimeScope.Dispose(); } }
AutofacServiceProvider类用于创建具体的对象。代码如下。IComponentContext参数会在Aotufac注入实例化时自动初始化。
private class AutofacServiceProvider : IServiceProvider { private readonly IComponentContext _componentContext; public AutofacServiceProvider(IComponentContext componentContext) { _componentContext = componentContext; } public object GetService(Type serviceType) { return _componentContext.ResolveOptional(serviceType); } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。