接着前一篇博文,将接口快速打包固定请求格式,不需要修改代码,可以自动完成接口调用,实际上就是生成了一个接口的代理类。
那么仅仅是接口请求代理,没有服务端怎么行?所以需要将实现接口的类部署为webapi的控制器。
这个时候ABP就登场了,原理需要查看官方文档。ABP就是实现了快速生成部署。
我就不说ABP的东西了,官方文档可以任意查阅。
因为ABP作为一种开源组件,集成的东西太多太全,作为小企业中的我们,复杂,不容易上手,所以打算跳过这个东西。
我需要的是把实现了业务接口的类部署成webapi即可,没有其它功用。
后面找到一个已经研究过的项目Dynamic Web AP。项目地址:https://github.com/dotnetauth/Panda.DynamicWebApi.git
作者博文地址:https://www.cnblogs.com/stulzq/p/11007770.html。
最近花时间看了看,其实就是asp中的AOP接口使用,只是我买平时开放用WebApi,没有采用。
研究了作者的东西,我感觉小项目是可以用的,原作者叫动态webapi,其实简单说就是webRPC.
我用netcore3用了下,有个别地方有差异。基本原理是合适的。
主要有2点:
1.根据自己的约定,设置某个类是控制器
2.根据判断的控制器类,按照aspnet core约束,修改其中的内容,让aspnet core将它认定为webapi.
这里我就不讲原作者的代码了,感兴趣的可以去看,我只讲我的,我们的差不多。
认定接口类是控制器的方法:
继承ControllerFeatureProvider类,该类就是mvc验证是控制器的类,里面有个方法IsController,返回true就表明当前类型是控制器。
我的代码中提供了配置,传入一个Fun类型委托,如果原来的判断不成功,就调用该委托,通过自定义方法检查是否是控制器。
注意:比较老版本该类是不能使用的,只能继承该类的实现接口,把源码抄过来。新版本才可以,把IsController方法修改成了虚拟方法。
修改约束的方法:
实现IApplicationModelConvention接口,逐步修改各级约束。其实按照aspnet core的使用。
就是按照信息处理。
最后创建的URL路由:api/域名称/控制器名称/方法名称。
里面的控制器名称可以设置,提供了配置方法。目前考虑不要侵入代码。
所以我的代码中提供配置,根据配置的名称分别查找控制器的常量,静态属性或者字段,获取值来设置控制器URL中的名称。
同理,版本信息,所属域都是这样。
简单的介绍就这样完了。
提供的建议:
如果你要按照这种解决方案,将实现接口的业务类快速部署,那么给一点点建议。
关于控制器名称,一种方式是固化格式,方便前端修改调用,例如,实现的业务类名称=接口名称+“Bil”,这样每个接口对应的控制器名称就有了。前端格式化实现请求就有路径了。另外可以在接口中添加常量,静态变量来设置,这样就符合后端实现了。
前端格式化实现时就可以反射获取接口中的值类设置URL.当前最后不要在业务接口中直接使用,而是让每一个业务接口都继承一个api的转用接口,在这个专用接口上面添加特性,常量,静态变量。这样就可以实现无代码侵入了。这部分工作在我的代码中没有,需要用户自己定义使用。ABP和原作者就是在代码中已经定义了,所以必须有特性或者类,而我的没有。这也是为什么他们需要添加特性或者继承,就是以此来判断控制器类或者名称,域的。
差不多了,慢慢看吧。
附带一点点说明:
netcore3有一些变化,把一些组件移除了,做第三方存在了,所以对应是有变化的。这里涉及的是JSON格式化,微软使用了自己定义的。System.Text.Json.而不是原来的第三方组件了。
所以Swagger也要使用最新的预览版,低版本报错。
我的示例用的是NSwag。使用NSwag.AspNetCore包。
最后说说我封装的库使用方法:
Startup中,
services.AddWebApiAssembly(null);//添加程序集
services.AddWebApiDirectory(null);//添加程序集目录
添加程序集,就是一般说的将控制器剥离的方式,内部封装了。
services.AddDynamicWebApi(new DynamicWebApiOptions() { ControllerFeature=(P)=> {
if (P.GetInterface(typeof(ICall).Name) == null)
{
return false;
}
return true;
} });
添加动态处理组件,就是封装整个过程的库,算是中间件吧。里面的ControllerFeature就是判断控制器的委托。