模块化开发
模块是相对独立的业务功能单元,通常根据业务领域进行划分。模块化开发可以提升代码的可维护性和复用性。
模块必须以
Mod后缀命名。
管理模块
通过studio中的模块管理界面,可以非常方便地创建和删除模块,工具会自动跨程序集处理模块相关的依赖关系。
也可以在解决方案根目录下使用 CLI 创建模块或服务:
perigon add module <模块名称> perigon add service <服务名称>
模块目录
模块自身在src/Modules中,是一个独立的项目。通常包括:
- Models: Dto模型
- Managers: 业务逻辑
- Services: 仅用于该模块的服务
- ModuleExtensions.cs:模块的扩展方法,用于注册模块相关的服务。
Tip
源代码生成器会在服务中自动注入模块的扩展方法,无需手动调用。
模块的实体在src/Definition/Entity项目中,通过目录名称(模块命名)进行区分。
模块的复用
模块可以跨解决方案进行复用,如客户管理模块,订单管理模块等。工具提供了模块的打包和安装命令,方便模块的分发和使用。
业务模块应保持独立,不应直接引用其他业务模块。需要跨模块复用时,通用类型、常量和工具等基础内容放在Share项目中;如果复用内容属于功能实现、不适合放入Share,则放入共享模块CommonMod,由需要它的业务模块引用。不要让一个业务模块依赖另一个具体业务模块。
打包模块
要进行打包,需要编辑ModuleExtensions.cs文件,该文件在创建模块时自动生成,如:
public static class ModuleExtensions { [DisplayName("Perigon::XXX")] [Description("注册 XXX 模块服务,包括密钥管理与 OAuth 核心逻辑")] public static IHostApplicationBuilder AddXXXMod(this IHostApplicationBuilder builder) { builder.AddModServices(); return builder; } private static IHostApplicationBuilder AddModServices(this IHostApplicationBuilder builder) { // ...模块相关服务注册,如添加后台服务 return builder; } }
[DisplayName]:用来表示作者名称和包的显示名,使用::分隔,如"Perigon::文件管理模块",如果没有发现::,则默认认为是作者名称,包显示名使用默认的模块名称。[Description]:用来描述包的作用和特点。AddXXXMod:模块的扩展方法,用来注册模块相关的服务,如果服务很多,可以拆分到私有方法AddModServices中。
Note
通常AddXXXMod只包含该模块特定的服务注册
进行打包的模块,要满足:
- 业务模块之间不能直接互相引用;共享内容按上文放入
Share或CommonMod。 - 当前 CLI 的打包依赖校验会检查 C#
using指令中的模块命名空间:模块源码和实体目录允许引用本模块及Share;所选服务的控制器目录还允许引用CommonMod。因此,模块源码直接引用CommonMod目前会被module pack校验拦截。
在项目根目录下使用perigon module pack <模块名称> <服务名称>打包,生成的 zip 文件位于package_modules目录。包内包含模块元数据和模块、实体目录;控制器和前端文件按需加入。典型布局如下:
metadata.json
Modules/<ModuleName>/...
Entity/<ModuleName>/...
Controllers/<ModuleName>/... # 可选
Frontend/<前端模块目录名>/... # 指定 --front-path 时
Frontend/share/... # 同级 share 目录存在时
metadata.json记录模块名、作者、显示名、描述和版本等信息;版本可通过-v/--version指定,省略时默认使用1.0.0。- 打包命令中的
<服务名称>是控制器来源服务。CLI 只检查src/Services/<服务名称>/Controllers/<模块名称>;目录存在时递归打入该目录下的文件,目录不存在时不包含控制器。它不会扫描其他服务,也不会按 C# 控制器类型筛选。打包时会跳过bin和obj目录。 - 需要打包前端模块时,使用
--front-path指定前端模块目录;该目录及其同级的share目录会分别写入Frontend/<模块目录名>和Frontend/share。详细规则见命令行文档。
安装模块
请在项目根目录下执行:
perigon module install <模块包路径> <服务名称>
安装命令中的<服务名称>是安装目标服务。CLI 会把包中的模块文件复制到src/Modules/<模块名称>,实体文件复制到src/Definition/Entity/<模块名称>;如果包内含Controllers/<模块名称>,则复制到src/Services/<服务名称>/Controllers/<模块名称>。目标位置已有同路径文件时,模块、实体和控制器文件会被覆盖。
复制文件后,CLI 会将模块加入解决方案,为目标服务项目添加模块项目引用,并更新服务的GlobalUsings.cs;如果找到DefaultDbContext.cs,还会根据模块实体补充DbSet及对应的 Entity Framework 全局 using。安装前请确认目标服务目录存在。
如果包中包含前端文件,安装时可用--front-path指定前端项目根目录,文件会恢复到其src/app/modules下。模块目录中的同名文件会覆盖;share目录中已存在的同名文件会保留,只补充缺少的文件。安装后重新加载解决方案并检查模块是否可正常构建。详细前端规则见命令行文档。