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 源码研读 - 依赖注入的主要内容,如果未能解决你的问题,请参考以下文章