使用.NET6打造动态API
source link: https://www.cnblogs.com/known/p/15499542.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
使用.NET6打造动态API
ApiLite是直接将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());
});
}
internal static WebApplication UseKApp(this WebApplication app)
{
...
return app;
}
}
//判断服务类型是否为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;
}
}
Recommend
-
6
.NET6 平台系列1 .NET Framework发展历程 系列目录
-
6
.NET6 平台系列2 .NET Framework框架详解系列目录 【已更新最新开发文章,点击查看详细】 什么是 .NET Framework? .NET...
-
6
.NET6系列:C#10新功能预览 - 张传宁 - 博客园系列目录 【已更新最新开发文章,点击查看详细】 2021年4月19日微软发布公告称将于今年夏季发布首款64位...
-
7
.NET Core/.NET5/.NET6 开源项目汇总7:电商项目 系列目录
-
10
前言# 随着.Net6的发布,微软也改进了对之前ASP.NET Core构建方式,使用了新的Minimal API模式。之前默认的方式是需要在Startup中注册IOC和中间件相关,但是在Min...
-
8
Minimal API 'Result.Stream()' Return Type[.NET6] In this article, we will know about a Minimal API return type that is 'Result.Stream()'Result.Stream():The 'Result.Ste...
-
4
.NET6使用DOCFX自动生成开发文档 本文内容来自我写的开源电子书《WoW C#》,现...
-
1
.net6&7中如何优雅且高性能的使用Json序列化 .net中的S...
-
13
卯兔敲门,新的一年,祝大家前‘兔’似锦!希望大家假后还能找到公司的大门 O(∩_∩)O !书接上文,我们使用了 Consul实现了服务注册与发现,对Consul...
-
7
1、🍕介绍 GRPC是一个高性能、通用的开源远程过程调用(RPC)框架,基于底层HTTP/2协议标准和协议层Protobuf序列化协议开发,支持众多的开发语言,由Google开源。 gRPC也是基于以下理念:定义一个服务,指...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK