[Asp.net 5] DependencyInjection项目代码分析2-Autofac
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); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?