Furion.Pure 动态 API 控制器生成 — 功能与实现原理
动态 API 控制器生成 — 功能与实现原理
一、核心功能
动态 API 控制器生成是 Furion/JNPF 框架的核心特性之一,它允许开发者创建普通的服务类(Service),无需继承ControllerBase,也无需手动写[Route]和[HttpMethod]特性,框架会自动将这些服务类转换为完整的 API 控制器。
核心价值:
- 零配置路由:服务类自动注册为 API 接口
- 命名约定驱动:方法名前缀自动映射 HTTP 方法
- 自动参数绑定:智能识别
[FromBody]、[FromRoute]等 - 模块化支持:支持外部程序集和插件动态加载
二、实现流程
1. 服务注册阶段
在 [Startup.cs]中调用:
services.AddControllers().AddDynamicApiControllers();[DynamicApiControllerServiceCollectionExtensions.cs]的核心逻辑:
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1 | 加载程序集部件 | 将所有项目程序集添加到ApplicationPartManager |
| 2 | 注册特性提供器 | 添加DynamicApiControllerFeatureProvider |
| 3 | 注册应用模型转换器 | 添加DynamicApiControllerApplicationModelConvention |
| 4 | 注册配置选项 | 添加DynamicApiControllerSettingsOptions |
2. 控制器识别机制
[DynamicApiControllerFeatureProvider.cs]继承自ControllerFeatureProvider,重写IsController()方法:
protectedoverrideboolIsController(TypeInfotypeInfo){returnPenetrates.IsApiController(typeInfo);}[Penetrates.cs]中的识别规则:
internalstaticboolIsApiController(Typetype){// 排除非公开、抽象类、接口、泛型类等if(!type.IsPublic||type.IsAbstract||type.IsInterface||type.IsGenericType)returnfalse;// 识别条件(满足任一即可):if(typeof(ControllerBase).IsAssignableFrom(type)// 继承 ControllerBase||typeof(IDynamicApiController).IsAssignableFrom(type)// 实现 IDynamicApiController||type.IsDefined(typeof(DynamicApiControllerAttribute))// 贴有 [DynamicApiController] 特性||type.IsDefined(typeof(RouteAttribute)))// 贴有 [Route] 特性{returntrue;}returnfalse;}3. 路由与 HTTP 方法自动生成
[DynamicApiControllerApplicationModelConvention.cs]实现了IApplicationModelConvention,在 MVC 应用模型构建阶段自动配置:
HTTP 方法映射规则:
| 方法名前缀 | HTTP 方法 |
|---|---|
Post、Add、Create、Insert、Submit | POST |
Get、Find、Fetch、Query | GET |
Put、Update | PUT |
Delete、Remove、Clear | DELETE |
Patch | PATCH |
路由模板生成逻辑:
// 默认路由格式:{DefaultRoutePrefix}/{Module}/[controller]/[action]// 默认值:api/system/userinfo/get三、实际应用示例
假设你有一个服务类:
publicclassUserInfoService{publicUserInfoOutputGetUserInfo(stringuserId){...}publicvoidCreateUser(UserInfoInputinput){...}publicvoidUpdateUser(UserInfoInputinput){...}publicvoidDeleteUser(stringuserId){...}}框架会自动生成以下 API:
| HTTP 方法 | 路由路径 | 说明 |
|---|---|---|
| GET | /api/system/userinfo/userinfo | 获取用户信息 |
| POST | /api/system/userinfo | 创建用户 |
| PUT | /api/system/userinfo | 更新用户 |
| DELETE | /api/system/userinfo | 删除用户 |
注意:默认会移除
Service后缀和方法名中的谓词前缀(Get/Post等)
四、配置选项
[DynamicApiControllerSettingsOptions.cs]提供了丰富的配置项:
| 配置项 | 默认值 | 说明 |
|---|---|---|
DefaultRoutePrefix | api | 默认路由前缀 |
DefaultHttpMethod | POST | 默认 HTTP 方法 |
LowercaseRoute | true | 小写路由 |
AbandonControllerAffixes | Service,Controller等 | 需要移除的控制器后缀 |
AbandonActionAffixes | Async | 需要移除的方法后缀 |
KeepVerb | false | 是否保留方法名中的谓词 |
五、整体架构图
┌─────────────────────────────────────────────────────────────┐ │ 应用启动阶段 │ ├─────────────────────────────────────────────────────────────┤ │ 1. AddControllers() │ │ └── 注册 MVC 服务 │ ├─────────────────────────────────────────────────────────────┤ │ 2. AddDynamicApiControllers() │ │ ├── 加载所有程序集到 ApplicationPartManager │ │ ├── 注册 DynamicApiControllerFeatureProvider │ │ └── 注册 DynamicApiControllerApplicationModelConvention │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ MVC 应用模型构建阶段 │ ├─────────────────────────────────────────────────────────────┤ │ 1. ControllerFeatureProvider.IsController() │ │ └── 扫描所有程序集,识别符合条件的类 │ ├─────────────────────────────────────────────────────────────┤ │ 2. DynamicApiControllerApplicationModelConvention.Apply() │ │ ├── 配置控制器名称(移除后缀) │ │ ├── 生成路由模板 │ │ ├── 根据方法名前缀映射 HTTP 方法 │ │ ├── 配置参数绑定(FromBody/FromRoute) │ │ └── 添加统一结果特性 │ └─────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ API 路由注册完成 │ │ (可通过 Swagger 查看) │ └─────────────────────────────────────────────────────────────┘六、总结
核心设计思想:通过命名约定和应用模型约定,将普通服务类自动转换为 API 控制器,大幅减少样板代码。
关键技术点:
- ASP.NET Core MVC 扩展点:利用
ControllerFeatureProvider和IApplicationModelConvention两个扩展点 - 反射扫描:在应用启动时扫描所有程序集,识别符合条件的服务类
- 约定优于配置:通过方法名前缀、类名后缀等约定自动生成路由和 HTTP 方法
- 模块化支持:支持外部程序集和插件动态加载
