Abp 源码研读 - 依赖注入

Posted rajesh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Abp 源码研读 - 依赖注入相关的知识,希望对你有一定的参考价值。

Abp 框架对于依赖注入的实现主要是依赖 Castle.Core ,实际上这一篇更应该归类于 Castle.Core 的应用, 若对 Castle.Core 知识不了解的, 可以先去学习下:Castle.Core 。下面来分析下比较重要的接口/类:

核心接口

IIocManager

定义了对 Ioc 对象, 服务注册,服务解析,服务注册与否的判断,以及对解析对象的释放、

IocManager

实现了 IIocManager 接口, 这里需要特别注意的是:对于长时间运行的程序,比如网站,Windows 服务, 并且需要创建大量的动态代理类, 那此时你就需要保证可以重用相同的 ProxyGenerator , 否则, 将会绕过缓存机制,导致CPU 使用率与内存耗用不断增加。

在程序实现中, 直接将 ProxyGenerator 声明为 static 即可, 另外将 IocManager 作为单例对象使用。

private static readonly ProxyGenerator ProxyGeneratorInstance = new ProxyGenerator();

IocContainer = new WindsorContainer(new DefaultProxyFactory(ProxyGeneratorInstance))

public static IocManager Instance get; private set;

static IocManager()

    Instance = new IocManager();

构造函数中通过静态变量 ProxyGeneratorInstance 初始化了 IWindsorContainer IocContainer , 紧接着,将当前对象(单例):

IocContainer.Register(
                Component
                    .For<IocManager, IIocManager, IIocRegistrar, IIocResolver>()
                    .Instance(this)
            );

进行注册为 IocManager, IIocManager, IIocRegistrar, IIocResolver, 这样, 我们通过 Ioc 解析出来的 这些对象都会返回当前实例。

约定注册

随着项目业务复杂度的提高, 需要注册的服务也会逐渐增多, 此时的管理就会逐渐繁杂。

在 Abp 中, 有以下几类 约定注册 的接口: (IConventionalDependencyRegistrar, BasicConventionalRegistrar

  • ITransientDependency
  • ISingletonDependency
  • IInterceptor
  • IConventionalDependencyRegistrar

ITransientDependency

瞬态服务:

Ioc 每次解析瞬态服务的时候都会返回一个新的瞬态服务对象

context.IocManager.IocContainer.Register(
                Classes.FromAssembly(context.Assembly)       //从当前上下文程序集中
                    .IncludeNonPublicTypes()                //包含非公共类型
                    .BasedOn<ITransientDependency>()         //ITransientDependency 的实现类
                    .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)  //排除泛型类型
                    .WithService.Self()                     //使用服务自身
                    .WithService.DefaultInterfaces()         //注册为默认接口
                    .LifestyleTransient()                   //设置生命周期形式为瞬态
                );

ISingletonDependency

单例服务:

字面意思,Ioc 会返回一个单例对象,在依赖注入容器中共享,约定注册的方式与瞬态非常相似:

context.IocManager.IocContainer.Register(
                Classes.FromAssembly(context.Assembly)
                    .IncludeNonPublicTypes()
                    .BasedOn<ISingletonDependency>()
                    .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                    .WithService.Self()
                    .WithService.DefaultInterfaces()
                    .LifestyleSingleton()                   // 设置生命周期形式为单例
                );

IInterceptor

拦截器:

对拦截器的注册

 context.IocManager.IocContainer.Register(
                Classes.FromAssembly(context.Assembly)
                    .IncludeNonPublicTypes()
                    .BasedOn<IInterceptor>()
                    .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                    .WithService.Self()
                    .LifestyleTransient()
                );

IConventionalDependencyRegistrar

依赖约定注册

/// <summary>
    /// This interface is used to register dependencies by conventions. 
    /// </summary>
    /// <remarks>
    /// Implement this interface and register to <see cref="IocManager.AddConventionalRegistrar"/> method to be able
    /// to register classes by your own conventions.
    /// </remarks>
    public interface IConventionalDependencyRegistrar
    
        /// <summary>
        /// Registers types of given assembly by convention.
        /// </summary>
        /// <param name="context">Registration context</param>
        void RegisterAssembly(IConventionalRegistrationContext context);
    

在参数 IConventionalRegistrationContext 中包含了当前程序集, IocManager 以及必要的注册配置, 这便于我们可以通过上下文获取到当前容器管理对象, 来完成对当前程序集中遵循约定的类型进行注册。

以上是关于Abp 源码研读 - 依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

ABP源码分析六:依赖注入的实现

3. abp依赖注入的分析.md

ABP理论学习之依赖注入

[Architect] ABP(现代ASP.NET样板开发框架) 依赖注入

ABP的依赖注入

基于DDD的.NET开发框架 - ABP依赖注入