[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);
            }
        }
时间: 2024-09-29 04:41:49

[Asp.net 5] DependencyInjection项目代码分析2的相关文章

[Asp.net 5] DependencyInjection项目代码分析4-微软的实现(3)

这个系列已经写了5篇,链接地址如下: [Asp.net 5] DependencyInjection项目代码分析 [Asp.net 5] DependencyInjection项目代码分析2-Autofac [Asp.net 5] DependencyInjection项目代码分析3-Ninject [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(1) [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(2) 如果想

[Asp.net 5] DependencyInjection项目代码分析4-微软的实现(5)(IEnumerable&lt;&gt;补充)

Asp.net 5的依赖注入注入系列可以参考链接: [Asp.net 5] DependencyInjection项目代码分析-目录 我们在之前讲微软的实现时,对于OpenIEnumerableService与ClosedIEnumerableService抛下没讲,现在我们就将该部分补充完整. 我们回忆ServiceProvider类的构造函数(对外部使用的)中,注册了IEnumerable<>.new OpenIEnumerableService(_table)的关系. public Se

[Asp.net 5] DependencyInjection项目代码分析-目录

微软DI文章系列如下所示: [Asp.net 5] DependencyInjection项目代码分析 [Asp.net 5] DependencyInjection项目代码分析2-Autofac [Asp.net 5] DependencyInjection项目代码分析3-Ninject [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(1) [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(2) [Asp.net

[Asp.net 5] DependencyInjection项目代码分析4-微软的实现(4)

这个系列已经写了6篇,链接地址如下: [Asp.net 5] DependencyInjection项目代码分析 [Asp.net 5] DependencyInjection项目代码分析2-Autofac [Asp.net 5] DependencyInjection项目代码分析3-Ninject [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(1) [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(2) [As

[Asp.net 5] DependencyInjection项目代码分析4-微软的实现(中)

在 DependencyInjection项目代码分析4-微软的实现(上)中介绍了“ServiceTable”.“ServiceEntry”.“IGenericService”.“IService”.“IServiceCallSite”,这篇介绍下“IGenericService."IService"."IServiceCallSite"实现类 GenericService类 做为IGenericService的唯一实现类,该类言简意赅,请看代码: internal

[Asp.net 5] DependencyInjection项目代码分析

最近在研究开源代码,正好发现Asp.net5的源码,下载地址:https://github.com/aspnet. 今天主要讲的是DependencyInjection这部分,抛砖引玉,供大家参考,也欢迎莅临斧正.闲话不多说,下面就代码进行简单分析 项目架构如下: 一共包含DependencyInjection.DependencyInjection.Abstractions.DependencyInjection.Autofac.DependencyInjection.Ninject以及Dep

[Asp.net 5] DependencyInjection项目代码分析3-Ninject

Microsoft.Framework.DependencyInjection.Ninject 该工程内部共包含5个类文件,底层使用Ninject实现依赖注入,工程截图如下: 从文件命名可以看出,NinjectServiceProvider和NinjectServiceScopeFactory分别是接口IServiceProvider和IServiceScopeFactory的实现类. (IServiceScope接口的实现类作为NinjectServiceScopeFactory内部类而存在,

[Asp.net 5] DependencyInjection项目代码分析4-微软的实现(上)

前面俩种实现中,很多内部细节都无法知道,微软的框架也是为了屏蔽具体实现,只让我们关注接口.但是人都是充满好奇的,依赖注入到底是怎么实现的呢? 微软又有怎样的实现呢?下面就为大家一一呈现(说实话,代码真不好读) 先看下核心类:ServiceTable internal class ServiceTable { private readonly object _sync = new object(); private readonly Dictionary<Type, ServiceEntry>

结对队友个人项目代码分析

项目要求 项目名称:中小学数学卷子自动生成程序 用户: 小学.初中和高中数学老师. 功能: 1.命令行输入用户名和密码,两者之间用空格隔开(程序预设小学.初中和高中各三个账号,具体见附表),如果用户名和密码都正确,将根据账户类型显示"当前选择为XX出题",XX为小学.初中和高中三个选项中的一个.否则提示"请输入正确的用户名.密码",重新输入用户名.密码: 2.登录后,系统提示"准备生成XX数学题目,请输入生成题目数量:",XX为小学.初中和高中三