zoukankan      html  css  js  c++  java
  • [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);
                    }
                }
            }
    View Code

     代码看起来挺多,实际也很简单对于列表进行循环遍历,对于每一项:如果注册类型不为空,使用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);
                }
            }
  • 相关阅读:
    Android px,dp,pt,sp的差别
    C 八皇后
    线性表
    android 推断手机是否支持前置摄像头
    C/C++易错难点笔记01
    Java日志记录的5条规则
    hdoj-1312-Red and Black
    oracle 11g sql developer安装后无法使用
    显示指定时间的秒数
    云端自动化测试方案
  • 原文地址:https://www.cnblogs.com/watermoon2/p/4512440.html
Copyright © 2011-2022 走看看