模块概述

谈到模块大家应该都不会感到陌生,不管是前端还是后端都有模块的概念,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)的更多相关文章

  1. XAF新手入门 - 前言

    很多小伙伴在第一次接触XAF时,会被它的丰富功能及开箱即用的特点所吸引,即使在不了解XAF的情况下,也能够依葫芦画瓢创建一个功能丰富的应用,但当应用到实际项目中时,你会发现与之前的愿景差距很大,很多都 ...

  2. python2.7入门---模块(Module)

        来,这次我们就看下Python 模块(Module).它是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句.模块让你能够有逻辑地组织你的 Pytho ...

  3. XAF新手入门 - 类型子系统(Types Info Subsystem)

    类型子系统概述 类型子系统是XAF的核心概念,但我们平时却很少关注它,它集中存储了模块中的类型,它是生成应用程序模型(Application Model)的基础,它与XAF中其它的概念都有所关联,了解 ...

  4. 新手入门指导:Vue 2.0 的建议学习顺序

    起步 1. 扎实的 JavaScript / HTML / CSS 基本功.这是前置条件. 2. 通读官方教程 (guide) 的基础篇.不要用任何构建工具,就只用最简单的 <script> ...

  5. 课程上线 -“新手入门 : Windows Phone 8.1 开发”

    经过近1个月的准备和录制,“新手入门 : Windows Phone 8.1 开发”系列课程已经在Microsoft 虚拟学院上线,链接地址为:http://www.microsoftvirtuala ...

  6. discuz插件开发新手入门 超详细

    作为一个新手,目前也是刚刚玩转discuz的插件功能,好东西不敢独享,就拿出来大家一起分享入门的过程.现在网上很多关于discuz的插件教程都是很简单的教程,原因可能是这个东西是商业化的东西,本着分享 ...

  7. discuz 插件开发 新手入门

    作为一个新手,目前也是刚刚玩转discuz的插件功能,好东西不敢独享,就拿出来大家一起分享入门的过程.现在网上很多关于discuz的插件教程都是很简单的教程,原因可能是这个东西是商业化的东西,本着分享 ...

  8. Xorboot-UEFI新手入门教程

    Xorboot-UEFI新手入门教程        Xorboot-UEFI是一款UEFI下轻量级的图形化多系统引导程序,pauly于2014年国庆节期间发布了预览版.搜了下论坛,关于Xorboot- ...

  9. 即时通讯新手入门:一文读懂什么是Nginx?它能否实现IM的负载均衡?

    本文引用了“蔷薇Nina”的“Nginx 相关介绍(Nginx是什么?能干嘛?)”一文部分内容,感谢作者的无私分享. 1.引言   Nginx(及其衍生产品)是目前被大量使用的服务端反向代理和负载均衡 ...

随机推荐

  1. BZOJ1176 [Balkan2007]Mokia(CDQ)

    CDQ裸题,\(x\), \(y\), \(tim\)三维偏序 #include <cstdio> #include <iostream> #include <cstri ...

  2. Java SE 16 新增特性

    Java SE 16 新增特性 作者:Grey 原文地址:Java SE 16 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...

  3. HDU6623 Minimal Power of Prime (简单数论)

    题面 T ≤ 50   000 T\leq50\,000 T≤50000 组数据: 输入一个数 N N N ( 2 ≤ N ≤ 1 0 18 2\leq N\leq 10^{18} 2≤N≤1018) ...

  4. 【PostgreSQL】PostgreSQL 15移除了Stats Collector

    试用即将发行的PostgreSQL 15的人会发现少了一个后台进程:​ postgres 1710 1 0 04:03 ? 00:00:00 /usr/pgsql-15/bin/postmaster ...

  5. vivo 基于 JaCoCo 的测试覆盖率设计与实践

    作者:vivo 互联网服务器团队- Xu Shen 本文主要介绍vivo内部研发平台使用JaCoCo实现测试覆盖率的实践,包括JaCoCo原理介绍以及在实践过程中遇到的新增代码覆盖率统计问题和频繁发布 ...

  6. windows系统-不能打印问题:PDF打印软件正常打开PDF文件,点击打印后软件卡死并提示未响应(No response)

    电脑突然出现PDF软件卡死问题,导致无法打印:初步思路记录: 导致问题出现的原因可能为文件问题(文件过大,打印机容量小).打印机问题(打印机未连接.故障等).电脑驱动问题(打印机驱动损坏).电脑补丁问 ...

  7. .Net Core 配置文件读取 - IOptions、IOptionsMonitor、IOptionsSnapshot

    原文链接:https://www.cnblogs.com/ysmc/p/16637781.html 众所周知,appsetting.json 配置文件是.Net 的重大革新之心,抛开了以前繁杂的xml ...

  8. 踩坑 Windows 服务来宿主 .NET 程序

    本文所指的 .NET 程序为 .NET6 的程序.因为 .NET 的版本更新很快,所以方式.方法也有变化,所以网上搜到的方法有些也过时了.以下是最近我实践下来的一点心得(坑). 上一篇说到 不安装运行 ...

  9. Centos7 安装部署Kubernetes(k8s)集群

    目录 一.系统环境 二.前言 三.Kubernetes 3.1 概述 3.2 Kubernetes 组件 3.2.1 控制平面组件 3.2.2 Node组件 四.安装部署Kubernetes集群 4. ...

  10. C++ 左值引用与 const 关键字

    左值引用是已定义的变量的别名,其主要用途是用作函数的形参,通过将左值引用变量用作参数,函数将使用原始数据,而不是副本.引用变量必须在声明时同时初始化,可将 const 关键字用于左值引用,如下所示: ...