使用.NET6實(shí)現(xiàn)動態(tài)API
ApiLite是基于.NET6直接將Service層生成動態(tài)api路由,可以不用添加Controller,支持模塊插件化,在項(xiàng)目開發(fā)中能夠提高工作效率,降低代碼量。
開發(fā)環(huán)境
- .NET SDK 6.0.100-rc.2.21505.57
- VS2022 Preview 7.0
項(xiàng)目地址
GitHub: https://github.com/known/ApiLite
項(xiàng)目目標(biāo)
- 根據(jù)Service動態(tài)生成api
- 支持自定義路由模板(通過Route特性定義)
- 支持模塊插件化
- 支持不同模塊,相同Service名稱的路由(命名空間需要有3級以上,例如:Com.Mod.XXX)
- 自動根據(jù)方法名稱判斷請求方式,Get開頭的方法名為GET請求,其他為POST請求
編碼約定
- 模塊類庫必須包含繼承IModule接口的類
- 需要生成api的Service必須繼承IService接口
- GET請求的方法必須以Get開頭
核心代碼
主要是ApiFeatureProvider和ApiConvention這兩個(gè)自定義類來動態(tài)生成api,ApiFeatureProvider繼承ControllerFeatureProvider,覆寫IsController方法,判斷服務(wù)類型是否符合Controller。ApiConvention實(shí)現(xiàn)了IApplicationModelConvention接口,實(shí)現(xiàn)動態(tài)添加Action。下面是主要代碼,完整代碼請?jiān)贕itHub上下載。
static class ServiceExtension { internal static WebApplicationBuilder AddKApp(this WebApplicationBuilder builder, Action<AppOption>? action = null) { var option = new AppOption(); action?.Invoke(option); ... AddDynamicApi(mvcBuilder, option);//添加動態(tài)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,這樣才能發(fā)現(xiàn)服務(wù)類 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()); }); } } //判斷服務(wù)類型是否為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); } } } ... //構(gòu)造路由模板 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; } }
以上所述是小編給大家介紹的使用.NET6實(shí)現(xiàn)動態(tài)API,希望對大家有所幫助。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
使用.NET6實(shí)現(xiàn)動態(tài)API
本文詳細(xì)講解了使用.NET6實(shí)現(xiàn)動態(tài)API,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12.Net?Core?配置文件讀取IOptions,IOptionsMonitor,IOptionsSnapshot
這篇文章主要介紹了.Net?Core配置文件讀取IOptions,IOptionsMonitor,IOptionsSnapshot,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09深入分析XmlSerializer對象的Xml序列化與反序列化的示例詳解
本篇文章是對XmlSerializer 對象的Xml序列化與反序列化的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05ASP.NET Web API教程 創(chuàng)建域模型的方法詳細(xì)介紹
本文將介紹幾種常見的創(chuàng)建域模型的方法,有需要的朋友可以適當(dāng)?shù)膮⒖?/div> 2012-11-11最新評論