说说ABP的依赖注入

上篇abp运行机制分析分析了ABP在启动时,都做了那些事;这篇我们来说说ABP的最核心的一部分:依赖注入(DependencyInjection),以下简称DI;

DI的概念我就不说了,关键字出来的资料非常多了,这里就不说了,这里主要讨论的是ABP是如何做到自依赖注入的(self register)

读过ABP的依赖注入文档内容我们知道:当你想注入一个服务时,最佳实践是根据命名规范(Naming conventions)来命名,也就是说,加入你想注入一个叫IPersonAppService的服务类,那么你的实现接口的服务类就应该按照Naming conventions规则命名为PersonAppService或者是保留“PersonAppService”字样,改成"Profix+PersonAppService"就能实现self register;否则的话就只能通过另写代码显示的注册接口与实现类;

其实这不是ABP框架这么要求的,这是ABP附带的DI组件——Castle Windsor这么要求的;让我们来看看ABP框架的代码就知道了

代码追踪

阅读过ABP文档的人应该知道,自依赖注入的关键入口是你项目的WebApplication.Module类的初始化方法Initialize下的IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());顾名思义,就是注册当前运行程序集所有按照命名规范的实现接口类;我们来看看IocManager属性,F12我们知道这是一个接口类IIocManager,继续追踪可以看出IIocManager继承两个接口,一个是Ioc注册接口IIocRegistrar和Ioc解析接口IIocResolver并且之前提到的Naming conventions以及abp运行机制分析知道IocManager就是IIocManager的实现类:

public interface IIocManager : IIocRegistrar, IIocResolver, IDisposable
{
IWindsorContainer IocContainer { get; }
new bool IsRegistered(Type type);
new bool IsRegistered<T>();
}
public class IocManager : IIocManager, IIocRegistrar, IIocResolver, IDisposable
{
.../
public void RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config);
public void RegisterAssemblyByConvention(Assembly assembly);
.../
}

public void RegisterAssemblyByConvention(Assembly assembly)内部调用了它的另一个重载函数RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config)并传一个默认规范注册选项配置,而这里配置类就仅仅只是设置一个是否自动按照命名规范注册接口实现类标识InstallInstallers,接着初始化ConventionalRegistrationContext上下文,然后遍历默认的规约注册器组注册去注册各种服务,最后根据InstallInstallers来判断是否调用self-register

public void RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config)
{
var context = new ConventionalRegistrationContext(assembly, this, config);
foreach (var registerer in _conventionalRegistrars)
{
registerer.RegisterAssembly(context);
}
if (config.InstallInstallers)
{
//这里这句话就是Castle Windsor在做的事,也就是按照命名规范实现自动注册服务关键所在
IocContainer.Install(FromAssembly.Instance(assembly));
}
}

上面这段代码有点要注意,就是foreach段,这里遍历一个注册器集合;这是在IocManager初始化时候就会初始化一个空的IConventionalDependencyRegistrar集合,然后在应用程序启动加载Module时就会增加一个默认实现类基础注册器BasicConventionalRegistrar,里面包含三种注册服务的细节——Transient,Singleton,Windsor Interceptors;

注入BasicConventionalRegistrar细节源代码如下:

public sealed class AbpKernelModule : AbpModule
{
public override void PreInitialize()
{
IocManager.AddConventionalRegistrar(new BasicConventionalRegistrar());
IocManager.Register<IScopedIocResolver, ScopedIocResolver>(DependencyLifeStyle.Transient);
IocManager.Register(typeof(IAmbientScopeProvider<>), typeof(DataContextAmbientScopeProvider<>), DependencyLifeStyle.Transient);
AddAuditingSelectors();
AddLocalizationSources();
AddSettingProviders();
AddUnitOfWorkFilters();
ConfigureCaches();
AddIgnoredTypes();
}
}

看到这里我相信ABP的依赖注入很清晰了;

下篇我们来说说ABP的缓存管理以及如何写自定义缓存管理类,学习下别人的框架是如何封装的,如何做到高可用,拓展性强的框架的

ABP的依赖注入的更多相关文章

  1. ABP框架 - 依赖注入

    文档目录 本节内容: 什么是依赖注入 传统方式的问题 解决方案 构造器注入模式 属性注入模式 依赖注入框架 ABP 依赖注入基础 注册依赖 约定注入 辅助接口 自定义/直接 注册 使用IocManag ...

  2. ABP之依赖注入

    写在开头 ABP开源项目最近有点小火,还开展了线下活动.本着学习DDD的心态与学习开源代码的的好奇,我也看了一遍ABP源码,在此将自己学习ABP的一些心得记录下来. 作为核心的IoC 作为一种解耦的方 ...

  3. (译)ABP之依赖注入

    原文地址:https://aspnetboilerplate.com/Pages/Documents/Dependency-Injection 什么是依赖注入 传统方式的问题 解决方案 构造函数注入 ...

  4. Asp.Net Core 3.1 Api 集成Abp项目依赖注入

    Abp 框架 地址https://aspnetboilerplate.com/ 我们下面来看如何在自己的项目中集成abp的功能 我们新建core 3.1 API项目和一个core类库 然后 两个项目都 ...

  5. ABP(现代ASP.NET样板开发框架)系列之6、ABP依赖注入

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之6.ABP依赖注入 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...

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

    ABP的依赖注入的实现有一个本质两个途径:1.本质上是依赖于Castle这个老牌依赖注入的框架.2.一种实现途径是通过实现IConventionalDependencyRegistrar的实例定义注入 ...

  7. ABP理论学习之依赖注入

    返回总目录 本篇目录 什么是依赖注入 传统方式产生的问题 解决办法 依赖注入框架 ABP中的依赖注入基础设施 注册 解析 其他 ASP.NET MVC和ASP.NET Web API集成 最后提示 什 ...

  8. ABP依赖注入

    ABP依赖注入 点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之6.ABP依赖注入 ABP是“ASP.NET Boilerplate Project (ASP.N ...

  9. ABP+AdminLTE+Bootstrap Table权限管理系统第四节--仓储,服务,服务接口及依赖注入

    在ABP框架中,仓储,服务,这块算是最为重要一块之一了.ABP框架提供了创建和组装模块的基础,一个模块能够依赖于另一个模块,一个程序集可看成一个模块, 一个模块可以通过一个类来定义这个模块,而给定义这 ...

随机推荐

  1. 一步步改造wcf,数据加密传输-匿名客户端加密传输(2)

    1         引言 前面的例子中, encodedValue这一串代码是自动生成的,所以在生产环境中,你需要安装一个VS201X,把代码放上去,然后刷新引用!!!就可以了,这么做的话,你可能是只 ...

  2. VS2017 v15.8.0 Task ExpandPriContent failed. Illegal characters in path

    昨天更新了VS到最新版本v15.8.0,但是编译UWP出现了操蛋的bug. 谷歌一下,vs社区已经有答案了. 打开.csproj文件,在节点 <PropertyGroup> 里面,加上一行 ...

  3. Python3.5 学习二十二

    回顾: 发送请求时:发送请求头和请求数据 request.META和request.request.body 响应请求时:响应头和响应返回数据 response.HEADER和response.bod ...

  4. SpringBoot2 配置

    一.Properties与Yaml SpringBoot支持properties与yaml两种配置文件application.properties/application.yml yaml简单使用 1 ...

  5. SVM的基础原理

    因为看cs231的时候用了一下multi-class的svm,所以又把svm给复习了一下,教材是周志华的西瓜书,这里是大概的笔记. 1.线性可分 对于一个数据集: 如果存在一个超平面X能够将D中的正负 ...

  6. spring boot实现异步调用

    今天在这里学习下使用springboot的异步调用async 首先使用@EnableAsync开启异步功能 /** * @author fengzp * @date 17/5/8 * @email f ...

  7. fetch更新本地仓库两种方式:

    来源:https://www.cnblogs.com/chenlogin/p/6592228.html //方法一 $ git fetch origin master //从远程的origin仓库的m ...

  8. 使用json-server模拟REST API

    https://segmentfault.com/a/1190000005793257 在开发过程中,前后端不论是否分离,接口多半是滞后于页面开发的.所以建立一个REST风格的API接口,给前端页面提 ...

  9. psutil 跨平台根据程序名杀进程

    笔者在项目中遇到过需要根据进程名杀进程的需求,利用python库psutil实现了此功能. 模块地址: https://pypi.python.org/pypi/psutil/   psutil功能 ...

  10. Mysql数据引擎和系统库

    系统数据库 information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息.列信息.权限信息.字符信息等performance_schema: MySQL ...