ABP源码分析四:Configuration
核心模块的配置
Configuration是ABP中设计比较巧妙的地方。其通过AbpStartupConfiguration,Castle的依赖注入,Dictionary对象和扩展方法很巧妙的实现了配置中心化。配置中心化是一个支持模块开发的框架必备功能。
ABP中核心功能模块中的一些功能的运行时的行为是依赖于一些外部配置的。这一点应该不难理解。 简单解释下,比如Localization这个功能模块,最基本Abp需要知道要做哪些语言的本地化。而这些具体的配置对于Abp底层框架来说是不可预知的,那么ABP底层框架就很有必要提供一种手段供外部模块自定义Congfiguration. 这就是下文要分析的IAbpStartupConfiguration和他的小伙伴们(各种I***Configuration)。 下图描述了这些Configuration之间的关系(稍后解释)。

(图一)
上面图中的都是接口,我们还需要知道这些接口的实例对象是在哪里生成的呢?
这要看回AbpBootstrapper的Initialize方法了(AbpBootstrapper在前面的文章已有介绍)。
首先,第一行通过AbpCoreInstaller注册的是系统框架级的所有configuration.
接着通过容器生成IAbpStartupConfiguration的实例AbpStartupConfiguration对象。
最后调用AbpStartupConfiguration的Initialize方法,该方法最终调用容器生成他的小伙伴的各种实例(****Configuration)。

(图二)

(图三)
ABP的作者为了方便管理,他把所有需要在ABP初始化阶段就要被实例化的接口都放到了Startup文件夹下(贴心啊!)。

(图四)
至此,ABP核心功能组件的Configuration就已经完成实例化了, 此后需要调用或修改某个组件的Configuration,只要引用其IAbpStartupConfiguration的实例Configuration即可访问各个组件的Configuration了。如下图AbpModule下的Configuration其实就是AbpStartupConfiguration,是一个单例。而Localization就是AbpStartupConfiguration实例的一个小伙伴LocalizationConfiguration。通过它就可以配置本地化了。同样的逻辑也适合其他****Configuration。

(图五)
自定义模块的配置
上面基本解释了Abp核心功能模块的配置的运作方式,接下来在分析下自定义module的Configuration 是如何实现的。下图描述了Abp中哪些原生Module会有自定义的configuration.(请注意箭头的方向,和第一张图中的箭头方向是相反的。)

Abp底层框架清楚有哪些核心功能模块,所以就很自然的给每个核心功能模块各自定义一个Configuration接口。但是Abp底层框架并不知道自定义的module有哪些,所以也就无法给每个自定义的module都创建一个Configuration接口。那么ABP底层框架是怎么管理每个自定义的module的Configuration的呢?
如果仔细观察图一的话,我们发现IAbpStartupConfiguration引用了一个IDictionaryBasedConfig的接口对象,IDictionaryBasedConfig的实现是DictionaryBasedConfig如下图。DictionaryBasedConfig下有个dictionary,这个就是最终保存自定义的module的Configuration的地方,因为Configuration的类型未知,所以dictionary的value是object类型。

下面以AbpWebModule为例讲一下自定义的module是如何实现Configuration。
第一步, 如下图, AbpWebModule定义了自己的接口IAbpWebModuleConfiguration和AbpWebModuleConfiguration,以及AbpConfigurationExtension

第二步, 如下图, 在AbpWebModule的preInitialize方法中将接口IAbpWebModuleConfiguration和其实现AbpWebModuleConfiguration注册到容器中。

第三步, 如下图, 看下AbpConfigurationExtension的实现。这是一个扩展方法,扩展了IModuleConfigurations接口,这个接口是在Abp底层框架中定义和实现的。其属性AbpConfiguration就是AbpStartupConfiguration实例。通过AbpStartupConfiguration的getorCreate方法(具体通过DictionaryBasedConfig来实现)就可以获取到AbpWebModule自定义的AbpWebModuleConfiguration的实例了。

具体访问方式如下,Configuration.Modules就是IModuleConfigurations的实例。通过其扩展方法AbpWeb访问AbpWebModuleConfiguration
Configuration.Modules.AbpWeb.SendAllExceptionsToClients=True;
最后这张图列出了AbpStartupConfiguration的所有可访问的configuration。

ABP源码分析四:Configuration的更多相关文章
- 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入
使用react全家桶制作博客后台管理系统 前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...
- ABP源码分析四十三:ZERO的本地化
ABP Zero模块扩展了ABP基础框架中的本地化功能,实现了通过数据库管理本地化的功能.其通过数据库保存本地化语言及其资源. ApplicationLanguage:代表本地化语言的实体类.一种语言 ...
- ABP源码分析四十七:ABP中的异常处理
ABP 中异常处理的思路是很清晰的.一共五种类型的异常类. AbpInitializationException用于封装ABP初始化过程中出现的异常,只要抛出AbpInitializationExce ...
- ABP源码分析四十:ZERO的Application和Tenant
ABP的Zero模块以数据库为数据源实现了ABP框架中的tenant management (multi-tenancy), role management, user management, ses ...
- ABP源码分析四十一:ZERO的Audit,Setting,Background Job
AuditLog: 继承自Entity<long>的实体类.封装AuditLog的信息. AuditingStore: 实现了IAuditingStore接口,实现了将AuditLog的信 ...
- ABP源码分析四十二:ZERO的身份认证
ABP Zero模块通过自定义实现Asp.Net Identity完成身份认证功能, 对Asp.Net Identity做了较大幅度的扩展.同时重写了ABP核心模块中的permission功能,以实现 ...
- ABP源码分析四十四:ZERO的配置
ABP Zero模块中需要配置的地方主要集中在三块:配置静态的role,配置外部认证源,以及配置本地化语言和资源. UserManagementConfig/IUserManagementConfig ...
- ABP源码分析四十五:ABP ZERO中的EntityFramework模块
AbpZeroDbContext:配置ABP.Zero中定义的entity的Dbset EntityFrameworkModelBuilderExtensions:给PrimitiveProperty ...
- ABP源码分析四十六:ABP ZERO中的Ldap模块
通过AD作为用户认证的数据源.整个管理用户认证逻辑就在LdapAuthenticationSource类中实现. LdapSettingProvider:定义LDAP的setting和提供Defaut ...
随机推荐
- [原] KVM 环境下MySQL性能对比
KVM 环境下MySQL性能对比 标签(空格分隔): Cloud2.0 [TOC] 测试目的 对比MySQL在物理机和KVM环境下性能情况 压测标准 压测遵循单一变量原则,所有的对比都是只改变一个变量 ...
- JavaScript基础知识总结(四)
JavaScript语法 八.函数 函数就是完成某个功能的一组语句,函数由关键字function + 函数名 + 加一组参数定义: 函数在定义后可以被重复调用,通常将常用的功能写成一个函数,利用函数可 ...
- python enumerate 用法
A new built-in function, enumerate() , will make certain loops a bit clearer. enumerate(thing) , whe ...
- 设计模式C#合集--工厂方法模式
简单工厂,代码: public interface ISpeak { public void Say(); } public class Hello : ISpeak { public void Sa ...
- xss和sql注入原理学习
8.4 Web跨站脚本攻击 8.4.1 跨站脚本攻击的原理(1) 跨站脚本在英文中称为Cross-Site Scripting,缩写为CSS.但是,由于层叠样式表 (Cascading Style ...
- 关于MJRefresh的下拉加载数据bug
当没有更多数据的时候显示NoMoreData 我的理解是先结束刷新再显示没有更多 今天之前一直没发现有问题 贴之前的代码 [self.collectionView reloadData]; [self ...
- HTML 学习笔记 JQuery(DOM 操作2)
接着上一节的将,这一节从复制节点讲起 复制节点 继续使用之前的例子 如果单击<li>元素后 需要在复制一个<li>元素,可以使用clone()方法完成.全部代码如下 <h ...
- mysql join 和left join 对于索引的问题
今天遇到一个left join优化的问题,搞了一下午,中间查了不少资料,对MySQL的查询计划还有查询优化有了更进一步的了解,做一个简单的记录: select c.* from hotel_info_ ...
- [PHP源码阅读]empty和isset函数
近日被问到PHP中empty和isset函数时怎么判断变量的,刚开始我是一脸懵逼的,因为我自己也只是一知半解,为了弄懂其真正的原理,赶紧翻开源码研究研究.经过分析可发现两个函数调用的都是同一个函数,因 ...
- Lesson 24 It could be worse
Text I entered the hotel manager's office and sat down. I had just lost £50 and I felt very upset. ' ...