接触到动态WebApi(Dynamic Web API)这个词的已有几年,是从ABP框架里面接触到的,当时便对ABP的这个技术很好奇,后面分析了一波,也尝试过从ABP剥离一个出来作为独立组件来使用,可是后来因与ABP依赖太多而放弃。十几天前朋友 熊猫 将这部分代码(我和他在搞事情)成功的从 ABP 中剥离出来并做了一个简单Demo扔给我,经过这么久(实在是太懒^_^)终于经过一些修改、添加功能、封装,现在已经能作为一个独立组件使用,项目开源在Github(https://github.com/dotnetauth/Panda.DynamicWebApi),希望觉得有用的朋友能给一个 Star 支持一下。
本文只讲使用,不讲原理,原理放到后面的文章中详细介绍。
二.介绍不管是传统的三层架构、 DDD 经典四层架构(DDD Lite),亦或是其他具有应用逻辑层(业务逻辑层)的架构,在Web应用程序开发当中 ,我们的业务逻辑最终都需要经过 Web Api 来进行调用,这里我们可能会有一个重复的操作:编写业务逻辑->编写API调用业务逻辑,这种重复性的操作有没有解决办法呢,我们编写完业务逻辑以后便给我们自动生成WebApi,答案当然是有的。
这里介绍一下本文的主角:Panda.DynamicWebApi(https://github.com/dotnetauth/Panda.DynamicWebApi)。源自于ABP的一个可独立使用的,可自动为你的业务逻辑层生成 ASP.NET Core WebApi 层的开源组件。它生成的API符合Restful风格,可以根据符合条件的类来生成WebApi,由MVC框架直接调用逻辑,无性能问题,完美兼容Swagger来构建API说明文档。
三.使用这里以 DDD 经典四层架构中的应用逻辑层来讲解。
1.准备(1)建立两个项目一个是应用逻辑层类库项目;一个是作为生成WebApi Host,ASP.NET Core WebApi项目
(2)编写应用逻辑
定义一个应用逻辑接口,所有应用逻辑都应实现它:
public interface IApplicationService { }定义一个学生管理逻辑接口,继承应用逻辑接口
public interface IStudentAppService : IApplicationService { /// <summary> /// 根据ID获取学生 /// </summary> /// <param></param> /// <returns></returns> StudentOutput Get(int id); /// <summary> /// 获取所有学生 /// </summary> /// <returns></returns> List<StudentOutput> Get(); /// <summary> /// 更新学生信息 /// </summary> /// <param></param> void Update(UpdateStudentInput input); /// <summary> /// 更新学生年龄 /// </summary> /// <param></param> void UpdateAge(int age); /// <summary> /// 根据ID删除学生 /// </summary> /// <param></param> void Delete(int id); /// <summary> /// 添加学生 /// </summary> /// <param></param> void Create(CreateStudentInput input); }实现学生逻辑管理接口:
public class StudentAppService: IStudentAppService { /// <summary> /// 根据ID获取学生 /// </summary> /// <param></param> /// <returns></returns> [HttpGet("{id:int}")] public StudentOutput Get(int id) { return new StudentOutput() {Id = 1, Age = 18, Name = "张三"}; } /// <summary> /// 获取所有学生 /// </summary> /// <returns></returns> public List<StudentOutput> Get() { return new List<StudentOutput>() { new StudentOutput(){Id = 1,Age = 18,Name = "张三"}, new StudentOutput(){Id = 2,Age = 19,Name = "李四"} }; } /// <summary> /// 更新学生信息 /// </summary> /// <param></param> public void Update(UpdateStudentInput input) { throw new System.NotImplementedException(); } /// <summary> /// 更新学生年龄 /// </summary> /// <param></param> [HttpPatch("{id:int}/age")] public void UpdateAge(int age) { throw new System.NotImplementedException(); } /// <summary> /// 根据ID删除学生 /// </summary> /// <param></param> [HttpDelete("{id:int}")] public void Delete(int id) { throw new System.NotImplementedException(); } /// <summary> /// 添加学生 /// </summary> /// <param></param> public void Create(CreateStudentInput input) { throw new System.NotImplementedException(); } }(3)给 WebApi Host 项目配置 Swagger。
Install-Package Swashbuckle.AspNetCore -Version 4.0.1Startup 中配置
public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new Info { Title = "晓晨学生管理系统 WebApi", Version = "v1" }); options.DocInclusionPredicate((docName, description) => true); options.IncludeXmlComments(@"bin\Debug\netcoreapp2.2\Xc.StuMgr.WebApiHost.xml"); options.IncludeXmlComments(@"bin\Debug\netcoreapp2.2\Xc.StuMgr.Application.xml"); }); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "晓晨学生管理系统 WebApi"); }); app.UseMvc(); }运行则会直接看到默认的 ValuesController 的5个API。
2.动态WebApi通过Nuget 为 Application 项目安装组件:
Install-Package Panda.DynamicWebApi为接口 IApplicationService继承 IDynamicWebApi同时添加特性DynamicWebApi
[DynamicWebApi] public interface IApplicationService:IDynamicWebApi { }在 WebApi Host 项目中,Startup里配置动态WebApi:
Startup.cs:
// 添加动态WebApi 需放在 AddMvc 之后 services.AddDynamicWebApi();然后打开浏览器访问将会看到: