MAUI 嵌入式 Web 架构实战(八)插件化 API 架构:Controller 自动发现与模块化扩展
MAUI 嵌入式 Web 架构实战(八)
插件化 API 架构:Controller 自动发现与模块化扩展
源码地址
https://github.com/densen2014/MauiPicoAdmin
在前面的系列文章中,我们已经逐步构建了一个完整的 MAUI + PicoServer 嵌入式 Web 服务架构:
- PicoServer 本地 Web Server
- REST API 接口体系
- Web Admin 管理后台
- 权限认证系统
- WebSocket 实时通信
随着系统不断扩展,一个新的架构问题出现了:
当 API 数量越来越多时,如何让服务器 自动发现并注册 API,而不是手动注册每个接口?
例如系统中可能逐渐出现:
/api/system/*
/api/device/*
/api/order/*
/api/storage/*
/api/user/*
如果每个 API 都需要手动注册:
api.AddRoute("/api/system/info", SystemInfo, "GET");
api.AddRoute("/api/device/start", DeviceStart, "POST");
api.AddRoute("/api/order/list", OrderList, "GET");
api.AddRoute("/api/storage/add", StorageAdd, "POST");
当接口达到几十甚至上百个时:
服务器启动代码会变得非常混乱。
因此,本篇我们将实现一种更优雅的架构:
Controller 自动发现 API 架构
核心能力:
[ApiController]标记 Controller[ApiRoute]标记 API- 反射扫描 Controller
- 自动注册 API
- 模块化接口体系
最终开发体验将变成:
[ApiController]
public class DeviceController
{
[ApiRoute("/api/device/list","GET")]
public object List()
{
return DeviceManager.GetDevices();
}
}
无需再手动注册 API。
服务器启动时将自动完成:
扫描 Controller
↓
扫描 API 方法
↓
自动注册 Route
一、目标架构
最终服务器结构:
MAUI App
│
└── PicoServer
│
├── API Core
│
├── Controller Scanner
│
└── Controllers
├── SystemController
├── DeviceController
├── OrderController
└── StorageController
服务器启动流程:
扫描 Controller
↓
扫描 API
↓
自动注册 Route
二、定义 ApiController 标记
首先定义 Controller 标记 Attribute:
[AttributeUsage(AttributeTargets.Class)]
public class ApiControllerAttribute : Attribute
{
}
使用方式:
[ApiController]
public class DeviceController
{
}
服务器扫描时只会加载带有:
[ApiController]
标记的类。
三、定义 API Route 特性
每个 API 使用 Attribute 描述:
namespace MauiPicoAdmin;
[AttributeUsage(AttributeTargets.Method)]
public class ApiRouteAttribute : Attribute
{
public string Path { get; }
public string? Method { get; }
public ApiRouteAttribute(string path)
{
Path = path;
}
public ApiRouteAttribute(string path, string? method)
{
Path = path;
Method = method;
}
}
使用方式:
[ApiRoute("/api/system/info","GET")]
public object Info()
{
return new
{
version = "1.0",
time = DateTime.Now
};
}
四、Controller 示例
一个完整 Controller:
[ApiController]
public class DeviceController
{
[ApiRoute("/api/device/list","GET")]
public object List()
{
return new
{
count = 5
};
}
[ApiRoute("/api/device/start","POST")]
public object Start()
{
return new
{
ok = true
};
}
}
写完 Controller:
API 就已经定义完成。
五、自动扫描 Controller
服务器启动时扫描程序集:
var asm = Assembly.GetExecutingAssembly();
var controllers = asm.GetTypes()
.Where(t => t.GetCustomAttribute<ApiControllerAttribute>() != null);
这样就能找到所有:
[ApiController]
类。
六、实例化 Controller
遍历 Controller:
foreach (var type in controllers)
{
var controller = Activator.CreateInstance(type);
RegisterController(controller);
}
七、扫描 API 方法
在 Controller 中扫描方法:
void RegisterController(object controller)
{
var methods = controller.GetType().GetMethods();
foreach (var method in methods)
{
var route = method.GetCustomAttribute<ApiRouteAttribute>();
if (route == null)
continue;
RegisterApi(route, controller, method);
}
}
这一步会找到所有带有:
[ApiRoute]
标记的方法。
八、自动注册 API
在 PicoServer 中统一使用:
api.AddRoute()
注册接口。
实现代码如下:
void RegisterApi(ApiRouteAttribute route, object controller, MethodInfo method)
{
Func<HttpListenerRequest, HttpListenerResponse, Task> handler = (request, response) =>
{
var result = method.Invoke(controller, new object[] { request, response });
return result as Task ?? Task.CompletedTask;
};
api.AddRoute(route.Path, handler, route.Method);
}
这样就把 Controller 方法自动转换为 API Route。
九、完整运行流程
服务器启动时执行:
ScanControllers();
完整流程:
扫描程序集
↓
找到 [ApiController]
↓
扫描方法
↓
找到 [ApiRoute]
↓
调用 api.AddRoute()
↓
完成 API 注册
最终所有 API 自动加载。
十、最终开发体验
开发 API 时只需要写 Controller:
[ApiController]
public class OrderController
{
[ApiRoute("/api/order/list","GET")]
public object List()
{
return OrderService.GetOrders();
}
}
服务器启动后自动注册:
GET /api/order/list
开发者 无需手动写任何:
api.AddRoute(...)
代码会变得非常简洁。
十一、架构优势
这种 API 架构带来的优势:
1 API 自动注册
避免大量:
api.AddRoute(...)
代码。
2 模块化开发
每个模块独立 Controller:
SystemController
DeviceController
OrderController
StorageController
UserController
结构非常清晰。
3 扩展简单
新增 API 只需要写:
[ApiRoute]
无需修改服务器代码。
4 为插件架构打基础
虽然本篇只扫描当前程序集,但未来可以扩展为:
扫描外部 DLL
加载 Controller
实现真正的:
插件化 API 系统。
十二、下一篇预告
在下一篇文章中,我们将继续升级架构:
PicoServer + PWA 离线系统
实现:
- 浏览器离线运行
- Service Worker
- 本地数据缓存
- 离线 Web Admin
- MAUI Web Shell
最终实现一个完整的:
离线 Web App
+
本地 API
+
MAUI Web Shell
一个真正的:
本地 Web 应用平台。
关联项目
FreeSql QQ群:4336577
BA & Blazor QQ群:795206915
Maui Blazor 中文社区 QQ群:645660665
知识共享许可协议
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名AlexChow(包含链接: https://github.com/densen2014 ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系 。
转载声明
本文来自博客园,作者:周创琳 AlexChow,转载请注明原文链接:https://www.cnblogs.com/densen2014/p/19699618
AlexChow
今日头条 | 博客园 | 知乎 | Gitee | GitHub


浙公网安备 33010602011771号