快速入门
简介
CMS.Plugin.MyPluginName 提供了完整的CRUD操作、数据导入导出、排序调整等功能。本快速入门指南将帮助新手开发者快速掌握插件的初始化配置、基本使用流程以及常见问题的解决方法。
该插件采用分层架构设计,包含以下核心层次:
- 应用层:处理业务逻辑和数据传输对象
- 领域层:实现核心业务规则和实体模型
- 基础设施层:提供数据访问和持久化支持
- 表示层:负责用户界面和API接口
项目结构概览
插件初始化配置
CMSPluginEntry类详解
CMSPluginEntry
是插件的核心入口点,负责插件的注册、配置和生命周期管理。
[EnableApplicationPart]
public class CMSPluginEntry : PluginEntry
{
private readonly IServiceCollection _service = new ServiceCollection();
public override void Register(IRegisteContext context)
{
var configuration = context.Features.GetConfiguration();
// 配置外部HttpApi
context.Services
.AddHttpApi<IMyPluginNameExternalApi>()
.ConfigureHttpApi(configuration.GetSection(nameof(IMyPluginNameExternalApi)));
// 注册插件特定的服务
context.Services.TryAddMyPluginName();
context.Services.AddScoped<IProjectRuntimeMigrator, CMSPluginRuntimeMigrator>();
context.Services.AddSingleton<IProjectService, MyPluginNameProjectService>();
// 配置数据库支持
_service.AddApplication<CMSPluginModule>(options =>
{
var databaseType = configuration[SectionName.DatabaseType] ?? "mysql";
if (KnowsDbCode.IsMysql(databaseType))
{
options.PlugInSources.Add(new TypePlugInSource(
typeof(MySQL.CMSPluginMySQLModule)
));
}
else if (KnowsDbCode.IsSqlServer(databaseType))
{
options.PlugInSources.Add(new TypePlugInSource(
typeof(SqlServer.CMSPluginSqlServerModule)
));
}
else if (KnowsDbCode.IsPostgreSql(databaseType))
{
options.PlugInSources.Add(new TypePlugInSource(
typeof(PostgreSql.CMSPluginPostgreSqlModule)
));
}
});
}
}
启动流程详解
数据库配置与支持
支持的数据库类型
CMS.Plugin.MyPluginName支持三种主流关系型数据库:
- MySQL:默认数据库类型,适合大多数Web应用场景
- PostgreSQL:功能强大的开源数据库,支持复杂查询
- SQL Server:微软企业级数据库解决方案
数据库配置示例
{
"ConnectionStrings": {
"Default": "Server=127.0.0.1;Database=CMS.Plugin.MyPluginName;User ID=root;Password=123456"
},
"SectionName": {
"DatabaseType": "mysql"
}
}
数据库模块选择机制
外部API集成
API配置与注册
插件支持通过HTTP客户端与外部系统进行集成:
// 在Register方法中配置外部API
context.Services
.AddHttpApi<IMyPluginNameExternalApi>()
.ConfigureHttpApi(configuration.GetSection(nameof(IMyPluginNameExternalApi)));
外部API配置示例
{
"IMyPluginNameExternalApi": {
"HttpHost": "http://127.0.0.1:18000/"
}
}
API集成架构
核心组件详解
应用服务层
应用服务层负责处理业 务逻辑和数据传输:
public class MyEntityNameAppService : CMSPluginAppService, IMyEntityNameAppService
{
private readonly IMyEntityNameRepository _myEntityNameRepository;
public MyEntityNameAppService(IMyEntityNameRepository myEntityNameRepository)
{
_myEntityNameRepository = myEntityNameRepository;
}
public virtual async Task<MyEntityNameDto> GetAsync(Guid id)
{
return ObjectMapper.Map<MyEntityName, MyEntityNameDto>(
await _myEntityNameRepository.GetAsync(id));
}
public virtual async Task<PagedResultDto<MyEntityNameDto>> GetListAsync(GetMyEntityNamesInput input)
{
var specification = new MyEntityNameSpecification(input.Name);
var count = await _myEntityNameRepository.GetCountAsync(input.Filter, specification);
var list = await _myEntityNameRepository.GetListAsync(input.Sorting, input.MaxResultCount,
input.SkipCount, input.Filter, specification);
return new PagedResultDto<MyEntityNameDto>(count,
ObjectMapper.Map<List<MyEntityName>, List<MyEntityNameDto>>(list));
}
}
控制器层
控制器层提供RESTful API接口:
[ApiController]
[Route("api/v{version:apiVersion}/MyPluginName/[controller]")]
public class MyEntityNameController : ControllerBase
{
private readonly IMyEntityNameAppService _myEntityNameAppService;
public MyEntityNameController(IMyEntityNameAppService myEntityNameAppService)
{
_myEntityNameAppService = myEntityNameAppService;
}
[HttpGet]
[Route("{id}")]
public virtual Task<MyEntityNameDto> GetAsync(Guid id)
{
return _myEntityNameAppService.GetAsync(id);
}
[HttpGet]
public virtual Task<PagedResultDto<MyEntityNameDto>> GetListAsync([FromQuery] GetMyEntityNamesInput input)
{
return _myEntityNameAppService.GetListAsync(input);
}
}
数据访问层
API使用指南
基础CRUD操作
获取单个实体
GET /api/v1/MyPluginName/MyEntityName/{id}
Authorization: Bearer {token}
响应示例:
{
"id": "guid",
"code": "ENTITY001",
"name": "测试实体",
"sort": 1,
"remark": "这是一个测试实体",
"extraProperties": {}
}
获取实体列表
GET /api/v1/MyPluginName/MyEntityName?filter=name&sorting=name&maxResultCount=10&skipCount=0
Authorization: Bearer {token}
创建实体
POST /api/v1/MyPluginName/MyEntityName
Content-Type: application/json
Authorization: Bearer {token}
{
"code": "NEW001",
"name": "新实体",
"sort": 2,
"remark": "新建实体描述"
}
更新实体
PUT /api/v1/MyPluginName/MyEntityName/{id}
Content-Type: application/json
Authorization: Bearer {token}
{
"code": "UPDATED001",
"name": "更新后的实体",
"sort": 3,
"remark": "更新后的描述",
"concurrencyStamp": "current-concurrency-stamp"
}
删除实体
DELETE /api/v1/MyPluginName/MyEntityName/{id}
Authorization: Bearer {token}
高级功能
导入功能
POST /api/v1/MyPluginName/MyEntityName/Import
Content-Type: multipart/form-data
Authorization: Bearer {token}
File: Excel文件
导出功能
GET /api/v1/MyPluginName/MyEntityName/Export?filter=name
Authorization: Bearer {token}
排序调整
PUT /api/v1/MyPluginName/MyEntityName/{id}/AdjustSort/{newSort}
Authorization: Bearer {token}
配置管理
关键配置项说明
appsettings.json配置
{
"IMyPluginNameExternalApi": {
"HttpHost": "http://127.0.0.1:18000/",
"Timeout": 30000,
"RetryCount": 3
},
"SectionName": {
"DatabaseType": "mysql",
"PluginState": "true"
},
"ConnectionStrings": {
"Default": "Server=localhost;Database=CMS.Plugin.MyPluginName;User ID=root;Password=password"
}
}
配置项详解
配置项 | 类型 | 默认值 | 说明 |
---|---|---|---|
IMyPluginNameExternalApi.HttpHost | String | http://127.0.0.1:18000/ | 外部API基础地址 |
SectionName.DatabaseType | String | mysql | 数据库类型:mysql/sqlserver/postgresql |
SectionName.PluginState | Boolean | true | 插件启用状态 |
ConnectionStrings.Default | String | - | 数据库连接字符串 |
设置管理
插件提供了统一的设置管理机制:
public static class CMSPluginMyPluginNameSettings
{
public const string PluginState = "SCMS.AppSettings.MyPluginName.PluginState";
}
常见问题排查
插件未正确加载
问题症状:插件无法正常启动或API不可用
排查步骤:
- 检查
CMSPluginEntry
类是否正确标记[EnableApplicationPart]
- 确认插件DLL文件已复制到应用程序的插件目录
- 验证插件依赖项是否完整安装
解决方案:
// 确保插件入口类正确配置
[EnableApplicationPart]
public class CMSPluginEntry : PluginEntry
{
// 实现必要的注册和配置方法
}
数据库连接失败
问题症状:应用程序启动时报数据库连接错误
排查步骤:
- 检查
appsettings.json
中的连接字符串配置 - 验证数据库服务器是否可用
- 确认数据库用户权限设置
解决方案:
{
"ConnectionStrings": {
"Default": "Server=localhost;Database=CMS.Plugin.MyPluginName;User ID=your_user;Password=your_password;Port=3306"
}
}
外部API调用失败
问题症状:外部API集成功能异常
排查步骤:
- 验证API地址配置是否正确
- 检查网络连通性
- 确认API认证凭据
解决方案:
{
"IMyPluginNameExternalApi": {
"HttpHost": "http://correct-api-host:port/",
"Timeout": 30000,
"Headers": {
"Authorization": "Bearer your-token"
}
}
}
性能优化建议
- 数据库索引优化:为常用查询字段添加索引
- 缓存策略:合理使用内存缓存减少数据库访问
- 批量操作:对于大量数据操作使用批量处理
- 异步处理:使用异步方法提高并发性能
最佳实践建议
开发规范
- 命名约定:遵循ABP框架命名规范
- 异常处理:使用
UserFriendlyException
提供友好的错误信息 - 日志记录:合理使用日志记录关键业务操作
- 单元测试:为关键业务逻辑编写单元测试
安全考虑
- 输入验证:对所有用户输入进行严格验证
- 权限控制:使用适当的授权过滤器保护API端点
- 数据加密:敏感数据应进行加密存储
- API安全:实施适当的API访问控制和限流
部署建议
- 环境隔离:不同环境使用不同的配置文件
- 监控告警:建立完善的监控和告警机制
- 备份策略:制定定期的数据备份计划
- 版本管理:使用版本控制系统管理代码变更
扩展开发
当需要扩展插件功能时:
- 遵循现有架构:保持与现有代码结构的一致性
- 模块化设计:将新功能封装为独立的模块
- 向后兼容:确保新版本与旧版本的兼容性
- 文档更新:及时更新相关技术文档
通过本快速入门指南,您应该能够:
- 理解CMS.Plugin.MyPluginName的基本架构和设计理念
- 掌握插件的初始化配置和基本使用方法