[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);

            }

        }

 

你可能感兴趣的:(dependency)