XAF新手入门 - 模块(Module)
模块概述
谈到模块大家应该都不会感到陌生,不管是前端还是后端都有模块的概念,XAF中的模块概念与大多数框架中的模块概念是相通的。XAF模块首先是一个.NET类库,同时它还包含一个继承自ModuleBase的Module类,Module类主要用于收集及对外暴露模块中的一些资源(BusinessObject、Controller、Action、Model、PropertyEditort等),同时XAF模块间的依赖与.NET类库间的依赖也是一致的,比如:A模块依赖B模块,B模块依赖C模块,那A模块同时拥有了B模块与C模块所提供的资源。XAF模块涵盖的功能很多,当前只对模块的部分功能进行介绍,后续还会与其它的概念一起介绍。
XAF默认提供了大量的基础功能模块(审计、图表、仪表盘、验证、报表、状态机等),你可以根据需要将这些模块添加到你的项目中。
项目结构
XAF项目主要包含应用程序项目与模块项目,当然也可以包含普通的.NET项目。应用程序项目是负责项目的启动,所以它需要指定平台(WinForm与Blazor),模块项目在不依赖特定平台时,是可以被其它应用程序项目或其它模块项目引用,依赖特定平台后,只能被特定平台的项目引用。
在XAF22.1之前的版本中,XAF项目中包含两种模块项目类型,一种是与平台相关的,一种是不相关的,在之后的版本中,将平台相关的模块代码移到了应用程序项目中,目的是为了简化项目结构。如果你想创建独立的模块,并且模块中包含了不同平台的代码,你还是需要创建平台相关的模块项目。
模块注册
模块注册分为两种,一种是模块间依赖的注册,一种是将模块注册到应用程序项目中,这两种注册方式是不一样的。
在整个XAF项目启动过程中模块是最先被初始化的,这里要引出一个概念Application(在不同的平台会有不同的实现,它们都是XafApplication的子类),从名字你就可以看出它在XAF中的地位,它上面挂载了运行XAF所需的所有资源,XAF模块当然也在其中,同时它还提供了丰富的功能,在WinForm项目中Application是以单例形式存在的,在Blazor项目中每一个会话都会有一个Application实例,现在你可以简单将Application理解为整个XAF应用的中心,后面会对它进行单独的介绍。
模块注册到应用程序项目中
在XAF22.1后,将模块注册到应用程序项目中WinForm与Blazor采用了相同的配置方式,下面以WinForm为例
上面的代码是ApplicationBuilder类中的片段,在XAF22.1后,WinForm项目都会存在一个ApplicationBuilder类,它是用于构建Application实例。接触过XAF的小伙伴对上面的代码应该比较容易理解,这里简单的解读一下,builder是IXafApplicationBuilder<TBuilder>的一个实例,在不同的平台(WinForm与Blazor)会有不同的实现。
builder.Modules是专门用于将模块注册到应用程序项目中的,它上有一个Add方法可以方便对模块进行注册,当然你也可以基于Add方法再作进一步的封装,例如:AddConditionalAppearance(ConditionalAppearance模块的注册方法),注册模块的先后顺序并不影响模块的加载。
在之前的XAF版本中,将模块注册到应用程序项目中,都是将模块中Module类的实例添加到Application.Modules中,新的注册方式可读性更强,目的是相同的,但将模块添加到Application.Modules中是在builder.Build()时执行的。
builder实例中包含一个_buildSteps委托集合,调用builder上的方法也就是向_buildSteps集合中添加委托(Action<XafApplication>),委托有一个Application参数,借用此参数可以对Application进行配置,最后的builder.Build()是将_buildSteps集合中的委托遍历并执行,并返回Application的一个实例。下面是Build方法简化后的代码
在模块注册到应用程序项目中时可以对模块进行配置,如果是自己的模块,首先需要在模块的Module类中添加对应的属性,如Test,在注册时直接给模块属性赋值,如下面的代码。如何使用模块Module类中的属性,将在后面进行介绍
如果你的模块是对外发布的,想更严谨一些,你可以参考XAF内部模块的做法,单独创建一个Options类,通过Options类收集模块配置,避免使用者直接给Module类中的属性赋值
模块间依赖的注册
在前面的介绍中,大家应该已经知道模块的依赖与.NET类库的依赖是相似的。一个XAF模块想依赖另一个XAF模块,首先要引用这个被依赖模块的类库,并在Module类的构造函数中,将被依赖模块中Module类的类型添加到RequiredModuleTypes中,代码如下:
由于RequiredModuleTypes的初始值是来自GetRequiredModuleTypesCore方法,所以我们也可以在Module类中重写GetRequiredModuleTypesCore方法来实现相同的操作,代码如下:
在上面的代码中,模块注册的先后顺序是不影响后续操作的,甚至依赖模块被无意中重复添加了,也不会有任何影响,因为模块在被正式加载时,会进行相应的过滤,当然最好不要这样做,下面的代码是可以正常运行的
模块加载
模块加载是在builder.Build()时进行的,模块加载的核心逻辑是放在ModuleList类中的。
这里简单说一下它的加载逻辑,ModuleList会先加载通过builder在应用程序项目中注册的模块,然后再去加载已加载模块的依赖模块,依赖模块再去加载自身的依赖模块,这里是一个递归,当然在加载过程中ModuleList会判断如果已被加载则跳过,最终会保证ModuleList中每一个模块类型只有一个模块实例,这里的ModuleList就是Application.Modules,你可以通过Application.Modules获取被加载的所有模块实例。
ModuleList类上有一个FindModule方法,可以使用它通过模块类型查找模块实例,那我们就可以在能够访问到Application的情况下,调用Application.Modules.FindModule查找模块实例,就可以访问到模块中的属性。
总结
模块在XAF中是一个比较重要的概念,模块中还很多知识点,这里只介绍了模块的注册与加载,在后续还会结合其它概念再介绍,同时还要注意在XAF22.1后,XAF项目结构进行了简化,同时模块在应用程序项目中的注册方式也不一样了。
注意:本系列文章只是讲解XAF中常用到的概念,方便大家理解,具体的操作方法还是需要参考官方文档
XAF新手入门 - 模块(Module)的更多相关文章
- XAF新手入门 - 前言
很多小伙伴在第一次接触XAF时,会被它的丰富功能及开箱即用的特点所吸引,即使在不了解XAF的情况下,也能够依葫芦画瓢创建一个功能丰富的应用,但当应用到实际项目中时,你会发现与之前的愿景差距很大,很多都 ...
- python2.7入门---模块(Module)
来,这次我们就看下Python 模块(Module).它是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句.模块让你能够有逻辑地组织你的 Pytho ...
- XAF新手入门 - 类型子系统(Types Info Subsystem)
类型子系统概述 类型子系统是XAF的核心概念,但我们平时却很少关注它,它集中存储了模块中的类型,它是生成应用程序模型(Application Model)的基础,它与XAF中其它的概念都有所关联,了解 ...
- 新手入门指导:Vue 2.0 的建议学习顺序
起步 1. 扎实的 JavaScript / HTML / CSS 基本功.这是前置条件. 2. 通读官方教程 (guide) 的基础篇.不要用任何构建工具,就只用最简单的 <script> ...
- 课程上线 -“新手入门 : Windows Phone 8.1 开发”
经过近1个月的准备和录制,“新手入门 : Windows Phone 8.1 开发”系列课程已经在Microsoft 虚拟学院上线,链接地址为:http://www.microsoftvirtuala ...
- discuz插件开发新手入门 超详细
作为一个新手,目前也是刚刚玩转discuz的插件功能,好东西不敢独享,就拿出来大家一起分享入门的过程.现在网上很多关于discuz的插件教程都是很简单的教程,原因可能是这个东西是商业化的东西,本着分享 ...
- discuz 插件开发 新手入门
作为一个新手,目前也是刚刚玩转discuz的插件功能,好东西不敢独享,就拿出来大家一起分享入门的过程.现在网上很多关于discuz的插件教程都是很简单的教程,原因可能是这个东西是商业化的东西,本着分享 ...
- Xorboot-UEFI新手入门教程
Xorboot-UEFI新手入门教程 Xorboot-UEFI是一款UEFI下轻量级的图形化多系统引导程序,pauly于2014年国庆节期间发布了预览版.搜了下论坛,关于Xorboot- ...
- 即时通讯新手入门:一文读懂什么是Nginx?它能否实现IM的负载均衡?
本文引用了“蔷薇Nina”的“Nginx 相关介绍(Nginx是什么?能干嘛?)”一文部分内容,感谢作者的无私分享. 1.引言 Nginx(及其衍生产品)是目前被大量使用的服务端反向代理和负载均衡 ...
随机推荐
- Spring源码 08 IOC refresh方法3
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- C++ 特殊矩阵的压缩存储算法
1. 前言 什么是特殊矩阵? C++,一般使用二维数组存储矩阵数据. 在实际存储时,会发现矩阵中有许多值相同的数据或有许多零数据,且分布呈现出一定的规律,称这类型的矩阵为特殊矩阵. 为了节省存储空间, ...
- 前端 | HTML5基础知识
1 HTML定义 HTML(英文Hyper Text Markup Language的缩写)中文译为"超文本标签语言",主要是通过HTML标签对网页中的文本.图片.声音等内容进行描 ...
- 操作 Excel 函数的快捷键
使用 Excel 函数的时候,需要用两个基本的快捷键来辅助写函数.输入函数时,Excel 会给出建议,选中函数之后不建议用回车键,因为这样做会出现#NAME?,直接使用Tab键即可.之后,通过Ctrl ...
- anltr 解析MYSQL
String sql = "select a as c,b as s,'zhange' F, 1/5 as e from t_order"; final MysqlQueryLex ...
- 「2020-2021 集训队作业」Yet Another Linear Algebra Problem(行列式,Binet-Cauchy 公式)
题面 出题人:T L Y \tt TLY TLY 太阳神:Tiw_Air_OAO 「 2020 - 2021 集 训 队 作 业 」 Y e t A n o t h e r L i n e a r A ...
- HandInDevil 的头发 (分 块)
题面 H a n d I n D e v i l \rm HandInDevil HandInDevil 的头发很油,因此随时有跳蚤跳上 H a n d I n D e v i l \rm HandI ...
- 关于stm32f10xRB系列的PB5和PB12外设冲突问题
上周在公司做了一个项目,调试一个mcu,本以为很简单的调试一下裸机驱动,但是调试过程中遇到了一些问题让我觉得比较有意思,记录一下. 1.关于stm32的SMBUS功能的介绍 由于笔者也没有玩过 ...
- 完全彻底的卸载MySQL5.7.35
最开始接触计算机的时候关于MySQL卸载的这个问题,导致我重装了一次系统.就在今天我又遇到了同样的问题. Setp①: 想要安装新的数据库软件必须要先彻底且干净的删除掉以前的数据库. 第一步要做的是停 ...
- django_day07
django_day07 django form组件 form组件的定义 class RegForm(forms.Form): user = forms.CharField(label='用户名') ...