跳到主要内容
版本:Next

后端开发

本章节介绍LMES系统后端组件的开发规范、流程和最佳实践。

一、先决条件

  • 开发环境: 比如 Visual Studio 2022 或者 Visual Studio Code 它需要支持 .NET 6.0+ 的开发.
  • 已安装 CMS2.0,并且掌握 CMS2.0 平台的操作使用
  • 有 c# 开发经验
  • 有 mysql、sql server 等数据库开发经验

二、插件模板

1、创建插件解决方案

我们将使用[.NET CLI ](dotnet 命令 - .NET CLI | Microsoft Learn) 来安装基于DDD分层架构的CMS2.0二次开发插件模板. 你可以在命令行终端中运行以下命令来安装它:

dotnet new install CMS.Plugin.Template.Ddd --nuget-source https://nexus.sycdev.com/repository/nuget-group/index.json

如果已经安装该模板,可以使用 dotnet new update 更新已安装的模板包。

image-20230307151942278

打开命令行终端并在终端中执行以下命令:

dotnet new cms-ddd -n TestPlugin -e Sample

image-20230320150814629

Commands

dotnet new cms-ddd -n MyPluginName -e MyEntityName

Options:

  • -n: 插件的名称
  • -e: 实体的名称

这将为TestPlugin插件创建一个基于DDD分层架构的解决方案,并添加Sample实体并创建CRUD服务。

image-20230307152239147

调试前请配置好数据库连接字符串:

**{CMSRootPath}**\host\appsettings.Development.json

image-20230320151445317

Code First 迁移:解决方案模版已经配置为使用Entity Framework Core的 Code First 迁移. 如果我们已经更改了数据库映射配置, 我们应该创建一个新的迁移并将更改应用于数据库。

image-20230307153324510

发布插件,插件作为独立运行的模块,也可以独立于项目进行发布。同样我们建议使用脚本发布,打开插件解决方案根目录,修改publish.ps1

image-20230307154222696

发布成功后,将按照插件名称,统一输出到插件解决方案根目录output\publish

2、为现有插件添加新的CRUD服务

我们将使用[.NET CLI ](dotnet 命令 - .NET CLI | Microsoft Learn) 来安装基于DDD分层架构的CMS2.0二次开发实体模板. 你可以在命令行终端中运行以下命令来安装它:

dotnet new install CMS.Plugin.Template.Ddd.Entity --nuget-source https://nexus.sycdev.com/repository/nuget-group/index.json

如果已经安装该模板,可以使用 dotnet new update 更新已安装的模板包。

image-20230320144340623

打开命令行终端并在终端中执行以下命令:

dotnet new cms-ddd-entity -n TestPlugin -e Order

image-20230320151628458

Commands

dotnet new cms-ddd-entity -n MyPluginName -e MyEntityName

Options:

  • -n: 插件的名称
  • -e: 实体的名称

这将为TestPlugin插件添加Order实体并创建CRUD服务。

image-20230320151949240

运行后打开Swagger UI,可以看到已经为我们的TestPlugin自动生成了Order文档

image-20230320152206939

3、如果已经安装模版,也可通过VS可视化界面生成插件代码

image-20231226133248499

三、解决方案简介

推荐 将解决方案命名:CMS.Plugin.PluginName,无特殊情况需保持文件目录结构需与解决方案目录结构一致。

image-20231208144721759

1、文档 (doc)

相关的组件文档

2、输出 (output)

编译输出文件夹,默认被忽略,不会上传到git服务器,用于存放编译或发布输出的临时文件。

3、源码 (src)

插件源代码。

4、测试 (test)

单元测试代码。

5、解决方案项 (Solution Items)

一般是放置在项目根目录中的各种配置文件

  • **NuGet.config:**在存储库的根目录中添加 nuget.config 文件。 这被认为是一种最佳做法,因为它促进了可重复性,并可确保不同的用户具有相同的 NuGet 配置。 可能需要配置 clear 元素以确保未应用任何用户或计算机特定的配置。
  • **README.md:**自述文件是一个组件的入门手册,里面介绍了整个组件的使用、功能等等。所以 README 文件写得好不好,关系到这个组件能不能更容易的被其他人了解和使用。
  • **publish.ps1:**发布脚本,用于发布插件,输出到项目根目录的output文件夹,可用于CI、CD自动化工具调用。
  • **.gitignore:**Git 忽略文件:使用该文件来选择性的上传文件。

四、源码分层

由于各插件形态不一,下面讲述的是基于DDD架构的插件分层,仅供参考,具体分层和架构以实际项目插件需要为准。

下面展示了一个分层良好的模块中的包以及它们之间的依赖关系:

image-20230227142049924

1、领域层

  • 推荐将领域层划分为两个项目:

    • Domain.Shared 包(项目) 命名为CMS.Plugin.PluginName.Domain.Shared,包含常量,枚举和其他类型, 它不能包含实体,存储库,域服务或任何其他业务对象. 可以安全地与模块中的所有层使用. 此包也可以与第三方客户端使用.

    • Domain 包(项目) 命名为CMS.Plugin.PluginName.Domain 包含实体, 仓储接口,领域服务接口及其实现和其他领域对象.

  • Domain 包依赖于 Domain.Shared 包.

2、应用服务层

  • 推荐将应用服务层划分为两个项目:

    • Application.Contracts 包(项目) 命名为CMS.Plugin.PluginName.Application.Contracts,包含应用服务接口和相关的数据传输对象(DTO).

      • Application contract 包依赖于 Domain.Shared 包.
    • Application 包(项目)命名为CMS.Plugin.PluginName.Application包含应用服务实现.

      • Application 包依赖于 Domain 包和 Application.Contracts 包.

3、基础设施层

  • 推荐为每个orm/数据库集成创建一个独立的集成包, 比如Entity Framework Core 和 MongoDB.
    • 推荐 例如, 创建一个抽象Entity Framework Core集成的CMS.Plugin.PluginName.EntityFrameworkCore 包. ORM 集成包依赖于 Domain 包.
    • 不推荐 依赖于orm/数据库集成包中的其他层.
  • 推荐 为每个主要的库创建一个独立的集成包, 在不影响其他包的情况下可以被另一个库替换.

4、插件启动层

  • 推荐 创建命名为CMS.Plugin.PluginName 包. **PluginEntry **为模块开发REST风格的HTTP API.

    • 虚线依赖:在上图中会发现用虚线表示了另外两个依赖,PluginEntry项目依赖了 ApplicationEntityFrameworkCore,理论上PluginEntry不应该依赖这两个项目,但实际上依赖了.原因如下:

      PluginEntry 是基座加载插件的启动,在启动程序注册服务是需要应用服务和仓储的实现类.

    • 推荐 为每个应用服务创建一个Controller (通常通过实现其接口). 这些控制器使用应用服务接口来委托操作. 它根据需要配置路由, HTTP方法和其他与Web相关的东西.

    • 推荐 只在PluginEntry层引入基座提供的包,其他层尽量不依赖基座.

五、最佳实践 & 约定

但是EF Core迁移系统在模块化环境中不是很好,在模块化环境中,每个模块都维护自己的数据库模式,而实际上两个或多个模块可以共享一个数据库.

模板已集成ABP 框架 大部分的基础设施,ABP 框架 提供了非常多的开箱即用的功能,开发代码前先阅读Abp文档,不要重复自己一次又一次地实现所有这些常见的东西.专注于你的业务代码,并让ABP按照约定自动执行。

六、插件打包发布

参阅《CMSv2插件打包工具说明.pdf》,使用插件打包工具进行插件打包。