编程语言
首页 > 编程语言> > Abp 源码研读 - 依赖注入

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

瞬态服务:

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 以及必要的注册配置, 这便于我们可以通过上下文获取到当前容器管理对象, 来完成对当前程序集中遵循约定的类型进行注册。

标签:注册,IocManager,type,Abp,WithService,源码,context,IocContainer,研读
来源: https://www.cnblogs.com/rajesh/p/11122412.html