类图:

作用:

abp中默认把对象的注册分为5中约定注册方式:

1.AbpAspNetCoreConventionalRegistrar

 public class AbpAspNetCoreConventionalRegistrar : IConventionalDependencyRegistrar
{
public void RegisterAssembly(IConventionalRegistrationContext context)
{
//ViewComponents
context.IocManager.IocContainer.Register(
Classes.FromAssembly(context.Assembly)
.BasedOn<ViewComponent>()
.If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
.LifestyleTransient()
); //PerWebRequest
context.IocManager.IocContainer.Register(
Classes.FromAssembly(context.Assembly)
.IncludeNonPublicTypes()
.BasedOn<IPerWebRequestDependency>()
.If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
.WithService.Self()
.WithService.DefaultInterfaces()
.LifestyleCustom<MsScopedLifestyleManager>()
);
}
}

2、ApiControllerConventionalRegistrar

 /// <summary>
/// Registers all Web API Controllers derived from <see cref="ApiController"/>.
/// </summary>
public class ApiControllerConventionalRegistrar : IConventionalDependencyRegistrar
{
public void RegisterAssembly(IConventionalRegistrationContext context)
{
context.IocManager.IocContainer.Register(
Classes.FromAssembly(context.Assembly)
.BasedOn<ApiController>()
.If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
.LifestyleTransient()
);
}
}

3、BasicConventionalRegistrar

 /// <summary>
/// This class is used to register basic dependency implementations such as <see cref="ITransientDependency"/> and <see cref="ISingletonDependency"/>.
/// </summary>
public class BasicConventionalRegistrar : IConventionalDependencyRegistrar
{
public void RegisterAssembly(IConventionalRegistrationContext context)
{
//Transient
context.IocManager.IocContainer.Register(
Classes.FromAssembly(context.Assembly)
.IncludeNonPublicTypes()
.BasedOn<ITransientDependency>()
.If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
.WithService.Self()
.WithService.DefaultInterfaces()
.LifestyleTransient()
); //Singleton
context.IocManager.IocContainer.Register(
Classes.FromAssembly(context.Assembly)
.IncludeNonPublicTypes()
.BasedOn<ISingletonDependency>()//如果服务继承了该接口就会自动注册为单例模式,这也就是我们使用ABP时对象自动创建神奇的地方了
.If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
.WithService.Self()
.WithService.DefaultInterfaces()
.LifestyleSingleton()
); //Windsor Interceptors
context.IocManager.IocContainer.Register(
Classes.FromAssembly(context.Assembly)
.IncludeNonPublicTypes()
.BasedOn<IInterceptor>()
.If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
.WithService.Self()
.LifestyleTransient()
);
}
}

4、ControllerConventionalRegistrar

 /// <summary>
/// Registers all MVC Controllers derived from <see cref="Controller"/>.
/// </summary>
public class ControllerConventionalRegistrar : IConventionalDependencyRegistrar
{
/// <inheritdoc/>
public void RegisterAssembly(IConventionalRegistrationContext context)
{
context.IocManager.IocContainer.Register(
Classes.FromAssembly(context.Assembly)
.BasedOn<Controller>()
.If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
.LifestyleTransient()
); //PerWebRequest
context.IocManager.IocContainer.Register(
Classes.FromAssembly(context.Assembly)
.IncludeNonPublicTypes()
.BasedOn<IPerWebRequestDependency>()
.If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
.WithService.Self()
.WithService.DefaultInterfaces()
.LifestylePerWebRequest()
);
}
}

5、FluentValidationValidatorRegistrar

  public class FluentValidationValidatorRegistrar : IConventionalDependencyRegistrar
{
public void RegisterAssembly(IConventionalRegistrationContext context)
{
context.IocManager.IocContainer.Register(
Classes.FromAssembly(context.Assembly)
.BasedOn(typeof(IValidator<>)).WithService.Base()
.LifestyleTransient()
);
}
}

当我们通过IocContainer调用AddConventionalRegistrar(Assembly assembly)这种方式注册时就会分别调用上面5个方法的RegisterAssembly()从assembly中查找是否有符合要求的对象,如果有就把该对象注册

使用场景如下:

[DependsOn(typeof(AbpWebCommonModule))]
public class AbpAspNetCoreModule : AbpModule
{
public override void PreInitialize()
{
IocManager.AddConventionalRegistrar(new AbpAspNetCoreConventionalRegistrar());//assembly调用次数由这里决定,如果5中约定注册方式都被添加了,就会查找5次,如果满足条件就注册 IocManager.Register<IAbpAspNetCoreConfiguration, AbpAspNetCoreConfiguration>(); Configuration.ReplaceService<IPrincipalAccessor, AspNetCorePrincipalAccessor>(DependencyLifeStyle.Transient);
Configuration.ReplaceService<IAbpAntiForgeryManager, AbpAspNetCoreAntiForgeryManager>(DependencyLifeStyle.Transient);
Configuration.ReplaceService<IClientInfoProvider, HttpContextClientInfoProvider>(DependencyLifeStyle.Transient); Configuration.Modules.AbpAspNetCore().FormBodyBindingIgnoredTypes.Add(typeof(IFormFile)); Configuration.MultiTenancy.Resolvers.Add<DomainTenantResolveContributor>();
Configuration.MultiTenancy.Resolvers.Add<HttpHeaderTenantResolveContributor>();
Configuration.MultiTenancy.Resolvers.Add<HttpCookieTenantResolveContributor>();
} public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(typeof(AbpAspNetCoreModule).GetAssembly());//此方法调用前必须在PreInitialize()中先调用IocManager.AddConventionalRegistrar才会起作用,否则对象不会被依赖注入
 } }

一般在模块注入时使用,相信大家经常这样用

那么为什么会执行5次注入呢?请看下面代码:

 /// <summary>
/// Adds a dependency registrar for conventional registration.
/// </summary>
/// <param name="registrar">dependency registrar</param>
public void AddConventionalRegistrar(IConventionalDependencyRegistrar registrar)
{
_conventionalRegistrars.Add(registrar);//这个变量是全局变量,用来当做缓存,如果IocManager. AddConventionalRegistrar()在模块中被调用5次约定注册方式,下面的循环就会跑5次
} /// <summary>
/// Registers types of given assembly by all conventional registrars. See <see cref="AddConventionalRegistrar"/> method.
/// </summary>
/// <param name="assembly">Assembly to register</param>
public void RegisterAssemblyByConvention(Assembly assembly)
{
RegisterAssemblyByConvention(assembly, new ConventionalRegistrationConfig());
} /// <summary>
/// Registers types of given assembly by all conventional registrars. See <see cref="AddConventionalRegistrar"/> method.
/// </summary>
/// <param name="assembly">Assembly to register</param>
/// <param name="config">Additional configuration</param>
public void RegisterAssemblyByConvention(Assembly assembly, ConventionalRegistrationConfig config)
{
var context = new ConventionalRegistrationContext(assembly, this, config); foreach (var registerer in _conventionalRegistrars)//循环几次由_conventionalRegistrars决定
{
registerer.RegisterAssembly(context);
} if (config.InstallInstallers)
{
IocContainer.Install(FromAssembly.Instance(assembly));
}
}

 这5中约定注册方式是ABP默认的,我们在开发中也可以根据自己的需求扩展自己需要的注入方式

欢迎批评和提建议!

待续.........................................

【原创】ABP之IConventionalDependencyRegistra接口分析的更多相关文章

  1. 【原创】ABP源码分析

    接口篇 IConventionalDependencyRegistra接口分析 待续.............. 模块篇 敬请期待...... 领域篇 敬请期待...... 消息篇 敬请期待..... ...

  2. 万水千山ABP - 系统发布后迁移 CodeFirst 数据库[原创]

    在项目开发的过程中,常会遇到项目发布后还变更数据库的情况.这时如何方便地进行数据库迁移呢 ? 下面直接列出操作的步骤: 1. 发布修改后的应用: 将最新版本的应用更新到目标机器中.更新的文件当然不包括 ...

  3. JS组件系列——在ABP中封装BootstrapTable

    前言:关于ABP框架,博主关注差不多有两年了吧,一直迟迟没有尝试.一方面博主觉得像这种复杂的开发框架肯定有它的过人之处,系统的稳定性和健壮性比一般的开源框架肯定强很多,可是另一方面每每想到它繁琐的封装 ...

  4. C# ABP源码详解 之 BackgroundJob,后台工作(一)

    本文归属作者所有,转发请注明本文链接. 1. 前言 ABP的BackgroundJob,用来处理耗时的操作.比如客户端上传文件,我们要把文件(Excel)做处理,这耗时的操作我们应该放到后台工作者去做 ...

  5. ABP 数据库 -- ABP&EF中的多表、关联查询

    本文介绍一下ABP中的多表查询. 1.创建实体 多表查询,在ABP或者EF中都很简单,这里我们创建一个Demo,一个学生实体.一个学校实体. 学校里面可以有很多学生,学生有一个学校. 实体如下: 学校 ...

  6. C# ABP 配置连接数据库&创建表

    1. 配置连接数据库 配置连接数据库很简单,只需要打开Web项目,然后找到Web.config,配置如下: <connectionStrings> <add name="D ...

  7. 最美应用API接口分析

    最美应用API接口分析html, body {overflow-x: initial !important;}.CodeMirror { height: auto; } .CodeMirror-scr ...

  8. ABP框架和NET CORE实战

    http://www.fishpro.com.cn/2017/09/ ABP实战系列 ABP实战 ABP-第一个Asp.net core 示例(7)AutoMapper的使用 我们为什么需要使用DDD ...

  9. ABP 切换mysql 数据库报错mysqlexception: incorrect string value: ‘\xe7\xae\x80\xe4\xbd\x93…’ for column display name

    刚折腾了ABP框架,为了跨平台,将SQL Server数据库换成了MySQL数据库,ABP框架上支持多语言,中间被字符集折腾的够呛,翻了N个博客,最后终于在StackOverFlow 上找到了最终的解 ...

随机推荐

  1. mysql 案例 ~查询导致的tmp临时文件问题

    一 简介:之前遇到一个tmp分区暴涨的问题,后来经过大神的指点,遂分析写下 二 分类: 1  select语句出现 using temporay tmp 下出现 #sql_631a_1.MYD #sq ...

  2. python - socketserver 模块应用

    server端: import socketserver import subprocess import json import struct class MyTCPHandler(socketse ...

  3. Shiro的三种授权(十二)

    前提就是在Realm的授权方法中查询出权限并返回List<String>形式 @Override protected AuthorizationInfo doGetAuthorizatio ...

  4. 【vim】查找重复的连续的单词

    当你很快地打字时,很有可能会连续输入同一个单词两次,就像 this this.这种错误可能骗过任何一个人,即使是你自己重新阅读一遍也不可避免.幸运的是,有一个简单的正则表达式可以用来预防这个错误.使用 ...

  5. nodejs 文件拷贝

    小文件拷贝 我们使用NodeJS内置的fs模块简单实现这个程序如下. var fs = require('fs'); function copy(src, dst) { fs.writeFileSyn ...

  6. VS C# xamarin 开发android 调试正常 发布分发后运行闪退出错

    我强烈推荐大家如果不是很有必要就不要引用一些.NET STD的库,比如json库newtonsoft.JSON,直接引用官方的system.Json就足够了,否则会导致体积变得巨大 好了废话不多说,这 ...

  7. centos6中创建软raid方法

    raid概述: 组建raid阵列命令: mdadm:模式化的工具 /etc/mdadm.conf     -A  Assemble 装配模式     -C  Create 创建模式     -C:专用 ...

  8. Android 项目中文件夹作用(res文件夹详细介绍)

    1. src:存放所有的*.Java源程序. 2. gen:为ADT插件自动生成的代码文件保存路径,里面的R.java将保存所有的资源ID. 3. assets:可以存放项目一些较大的资源文件,例如: ...

  9. Mac下brew安装与配置mysql

    一.打开mac控制台 $ brew install mysql 二.启动mysql服务 $ mysql.server start 三.初始化mysql配置 1 rainMacBook-Pro:~ co ...

  10. CF126B

    CF126B Password 题意: 给出一个字符串 H,找一个最长的字符串 h,使得它既作为前缀出现过.又作为后缀出现过.还作为中间的子串出现过. 解法: 沿着 $ next_n $ 枚举字符串, ...