使用.NET6实现动态API
ApiLite是基于.NET6直接将Service层生成动态api路由,可以不用添加Controller,支持模块插件化,在项目开发中能够提高工作效率,降低代码量。
开发环境
- .NET SDK 6.0.100-rc.2.21505.57
- VS2022 Preview 7.0
项目地址
- GitHub: https://github.com/known/ApiLite
项目目标
- 根据Service动态生成api
- 支持自定义路由模板(通过Route特性定义)
- 支持模块插件化
- 支持不同模块,相同Service名称的路由(命名空间需要有3级以上,例如:Com.Mod.XXX)
- 自动根据方法名称判断请求方式,Get开头的方法名为GET请求,其他为POST请求
编码约定
- 模块类库必须包含继承IModule接口的类
- 需要生成api的Service必须继承IService接口
- GET请求的方法必须以Get开头
核心代码
主要是ApiFeatureProvider和ApiConvention这两个自定义类来动态生成api,ApiFeatureProvider继承ControllerFeatureProvider,覆写IsController方法,判断服务类型是否符合Controller。ApiConvention实现了IApplicationModelConvention接口,实现动态添加Action。下面是主要代码,完整代码请在GitHub上下载。
static class ServiceExtension
{
internal static WebApplicationBuilder AddKApp(this WebApplicationBuilder builder, Action<AppOption>? action = null)
{
var option = new AppOption();
action?.Invoke(option);
...
AddDynamicApi(mvcBuilder, option);//添加动态api
return builder;
}
private static void AddDynamicApi(IMvcBuilder builder, AppOption option)
{
builder.ConfigureApplicationPartManager(m =>
{
m.ApplicationParts.Add(new AssemblyPart(typeof(IService).Assembly));
foreach (var item in option.Modules)
{
item.Initialize();//初始化模块
//将模块添加到ApplicationParts,这样才能发现服务类
var assembly = item.GetType().Assembly;
m.ApplicationParts.Add(new AssemblyPart(assembly));
}
m.FeatureProviders.Add(new ApiFeatureProvider());
});
builder.Services.Configure<MvcOptions>(o =>
{
o.Conventions.Add(new ApiConvention());
});
}
}
//判断服务类型是否为Controller
class ApiFeatureProvider : ControllerFeatureProvider
{
protected override bool IsController(TypeInfo typeInfo)
{
if (!typeof(IService).IsAssignableFrom(typeInfo) ||
!typeInfo.IsPublic ||
typeInfo.IsAbstract ||
typeInfo.IsGenericType)
return false;
return true;
}
}
class ApiConvention : IApplicationModelConvention
{
public void Apply(ApplicationModel application)
{
foreach (var controller in application.Controllers)
{
var type = controller.ControllerType;
if (typeof(IService).IsAssignableFrom(type))
{
ConfigureApiExplorer(controller);
ConfigureSelector(controller);
}
}
}
...
//构造路由模板
private string GetRouteTemplate(ActionModel action)
{
if (action.Attributes != null && action.Attributes.Count > 0)
{
foreach (var item in action.Attributes)
{
if (item is RouteAttribute attribute)
{
return attribute.Path;//返回自定义路由
}
}
}
var routeTemplate = new StringBuilder();
//routeTemplate.Append("api");
var names = action.Controller.ControllerType.Namespace.Split('.');
if (names.Length > 2)
{
//支持不同模块相同类名,添加命名空间模块名作前缀
routeTemplate.Append(names[^2]);
}
// Controller
var controllerName = action.Controller.ControllerName;
if (controllerName.EndsWith("Service"))
controllerName = controllerName[0..^7];
routeTemplate.Append($"/{controllerName}");
// Action
var actionName = action.ActionName;
if (actionName.EndsWith("Async"))
actionName = actionName[..^"Async".Length];
if (!string.IsNullOrEmpty(actionName))
routeTemplate.Append($"/{actionName}");
return routeTemplate.ToString();
}
}
使用示例
KHost.Run(args, o =>
{
o.Modules.Add(new TestModule());//添加模块
});
class TestModule : IModule
{
public void Initialize()
{
}
}
public class TestService : IService
{
public string GetName(string name)
{
return $"Hello {name}";
}
public string SaveData(string data)
{
return $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {data}";
}
[Route("api/test")]
public string GetCustMethod(string id)
{
return id;
}
}
原文链接:https://www.cnblogs.com/known/p/15499542.html
使用.NET6实现动态API的更多相关文章
- 使用.NET6打造动态API
ApiLite是直接将Service层自动生成api路由,可以不用添加Controller,支持模块插件化,在项目开发中能够提高工作效率,降低代码量. 开发环境 .NET SDK 6.0.100-rc ...
- Spring Cloud Zuul 2(基于配置中心的动态API网关)
在大体了解了API Zuul 和 配置中心Config后我们来尝试完成一个基于配置中心的动态API网关 创建项目 命名为api-gateway-dynamic-route并加入config 和 Zuu ...
- ABP 基于DDD的.NET开发框架 学习(六)创建新动态Api
我们想要这个服务暴露成一个Web API控制器,以方便客户端调用.ASP.NET Boilerplate能够自动且动态地为这个应用服务创建Web API 控制器,只需要一行配置代码即可完成. Dyna ...
- ABP框架 - 动态Web Api层
文档目录 本节内容: 创建动态Web Api控制器 ForAll 方法 重写 ForAll ForMethods Http 动词 WithVerb 方法 HTTP 特性 命名约定 Api 浏览器 Re ...
- DDD开发框架ABP之动态Web API层
建立动态Web API 控制器 ASP.NET Boilerplate 能够自动为您的应用层产生Web API层.比如说我们有如下的一个应用服务: public interface ITaskAppS ...
- ABP官方文档翻译 5.2 动态We API层
动态Web APID层 创建动态Web API控制器 ForAll方法 重写ForAll ForMethods Http动词 WithVerb方法 HTTP特性 命名约定 API管理器 RemoteS ...
- 动态We API(ABP官方文档翻译)
动态Web API层 创建动态Web API控制器 ForAll方法 重写ForAll ForMethods Http动词 WithVerb方法 HTTP特性 命名约定 API管理器 RemoteSe ...
- .Net Core后端架构实战【2-实现动态路由与Dynamic API】
摘要:基于.NET Core 7.0WebApi后端架构实战[2-实现动态路由与Dynamic API] 2023/02/22, ASP.NET Core 7.0, VS2022 引言 使用过ABP ...
- 动态WebApi
动态WebApi实现了直接对Service的调用,其实没有跨过ApiController,只是我们自己创建出ApiController 实现主要分以下几步 一 对默认WebApi服务的替换 ApiGl ...
- Robot Framework - 3 - 测试库API
08- 创建测试库--发布测试库 ***** 测试库文档 为了便于维护,测试库文档应该从源代码中生成. Robot Framework 有自己的文档工具 libdoc.py生成 API 文档. 一个 ...
随机推荐
- Windows下生成RSA公钥和私钥
打开E:\MAMP\bin\apache(服务器安装文件目录)文件夹下的 bin 文件夹,执行 openssl.exe 文件 生成 RSA 私钥,出现图中提示说明生成成功 genrsa -out rs ...
- C# 方块热力图
这张图右侧,0 3 6...... 30表示每个数字出现的次数,左侧就是每个数字出现次数的方块颜色图. 具体的思路是,找两个颜色 渐变的画出右侧的色条. 计算所有数字的最大最小次数,然后用他们色条 ...
- JavaScript 中 toString 的奇妙使用
JavaScript 中的toString()方法,我们通常会一些其他类型的变量,转为字符串类型.但这里还有一些其他奇妙的用法. 不同的类型调用 toString() 会得到不同的结果.我们来一一分析 ...
- 7.18考试总结(NOIP模拟19)[u·v·w]
我们不是狼,我们只是长着獠牙的羊...... 前言 我真 TM 爱死 \(\frac{1}{4}\) 了. 老实说,这套题是真恶心,第一题还有一点思路,到了后面是一点都搞不定了. 总的来说,主要原因是 ...
- sort awk 文本处理命令
sort: 1.将文件的每一行作为一个单位,相互比较 2.默认升序 3.以字符来进行对比,从首字符开始往后,依次按ASCII码值排序 sort 显示文件内容 (类似cat) 选项: -u 去掉重复行 ...
- umount 报错umount: /new_room: target is busy. (In some cases useful info about processes that use the device is found by lsof(8) or fuser(1))
挂载逻辑卷后,尝试更新逻辑卷的文件系统 [root@server lost+found]# umount /new_room/ umount: /new_room: target is busy. ( ...
- 算法金 | 再见,PCA 主成分分析!
大侠幸会,在下全网同名[算法金] 0 基础转 AI 上岸,多个算法赛 Top [日更万日,让更多人享受智能乐趣] 1. 概念:数据降维的数学方法 定义 主成分分析(PCA)是一种统计方法,通过正交变 ...
- react 装饰器
使用装饰器定义 装饰器是一种函数,写成 @函数名.它可以放在类和类方法的定义前面.react脚手架创建的项目默认是不支持装饰器,需要手动安装相关模块和添加配置文件. 安装相关模块 npm i -D c ...
- Linux Topicons Plus桌面工具安装
Topicons Plus是Linux系统GNOME桌面环境的工具,方便于在工具栏显示应用小图标. 1.进入GNOME商店搜搜下载TopIcons Plus工具.下载路径:https://extens ...
- npm 发布自己的组件库
npm 发布组件库步骤 第一步:注册 npm 账号 第二步:编写自己的组件库 第三部:编写 package.json 可以通过命令生成 npm init { "name": &qu ...