在Asp.Netcore内Panda.DynamicWebApi的使用方法,以及如何使用Panda.DynamicWebApi来使Controller何Server解耦
【一】 CodeFirst+DDD项目结构的构建
【二】Asp.Netcore使用Panda.DynamicWebApi来进行Controller解耦
【三】Asp.NetCore使用Efcore+Mysql实现CodeFirst
【四】EfCore实现全自动化迁移
案例代码下载点击
当我们把Controller单独建成一个项目来解耦Controller后,Api那边进行了引用,发现接口并没有生成,但是我们需要接口生成。通过Abp我们知道了需要动态生成接口,于是找到了一个动态生成接口的组件:Panda.DynamicWebApi。
引用官方的一段话
Panda.DynamicWebApi
是一个动态生成WebApi的组件,生成的API符合Restful风格,受启发于ABP。它可以根据符合条件的类来生成WebApi,由MVC框架直接调用逻辑,无性能问题,完美兼容Swagger来构建API说明文档,与手动编写Controller相比并无区别。
应用场景:DDD架构中的应用逻辑层,可使用本组件来直接生成WebApi,而无需再用Controller来调用。
git地址:https://github.com/dotnetauth/Panda.DynamicWebApi/blob/master/README_zh-CN.md
【二】Controller使用Panda.DynamicWebApi
1、首先理解Panda.DynamicWebApi组件动态生成webApi的机制。
(1)要让类生成动态API需要满足两个条件,一个是该类直接或间接实现 IDynamicWebApi
,同时该类本身或者父抽象类或者实现的接口具有特性 DynamicWebApi
(2)添加特性 [NonDynamicWebApi]
可使一个类或者一个方法不生成API,[NonDynamicWebApi]
具有最高的优先级
更多机制请看git源码那里的第二步有详细介绍
2、开始载入组件
(1)在Api项目上管理Nuget包里面搜索并安装Panda.DynamicWebApi和Swashbuckle.AspNetCore(该组件时swagger组件),给Controller项目上安装Panda.DynamicWebApi,如图所示:
(2)在Api项目上注入该组件。
删除Api上面的Controller文件夹,使Api项目如下图所示
在Startup文件里的ConfigureServices方法下添加如下代码
//动态生成Api接口
services.AddDynamicWebApi();
//配置SwaggerApi自动生成器
services.AddSwaggerGen(options =>
{
options.DocInclusionPredicate((docName, description) => true);//swagger支持动态生成的api接口
options.CustomSchemaIds(type => type.FullName); //swagger支持动态生成的api接口
options.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//获取代码运行的相对路径
options.IncludeXmlComments(Path.Combine(basePath, "Api.xml"), true);//插入代码上的注释放入Swagger
options.IncludeXmlComments(Path.Combine(basePath, "ApiController.xml"), true);
});
在Startup文件里的Configure方法下添加如下代码
//使用SwaggerApi自动生成器
app.UseSwagger();
//使用SwaggerApi自动生成器的Ui界面
app.UseSwaggerUI(option =>
{
option.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
这样添加完成后,由于之前Api项目引用了Controller项目,只要Controller项目里面满足Panda.DynamicWebApi的接口生成机制(直接或间接实现 IDynamicWebApi+具有DynamicWebApi特性
)就会自动生成接口,并且会在swagger(不了解Swagger的可以点击来进行详细了解)上显示出来,如下:
在Controller项目添加一个TestController的测试类
代码如下:
using Panda.DynamicWebApi;
using Panda.DynamicWebApi.Attributes;
namespace Controller
{
[DynamicWebApi]
public class TestController : IDynamicWebApi
{
public string GetHelloWorld()
{
return "Hello World !!";
}
}
}
启动Api项目,将会在Swagger上看到该接口,如图:
(3)在上面的这些步骤,我们完成Controller的解耦,Controller的代码可以写在别的项目了,而主项目只需要添加对该项目的引用即可,在为了方便,我们不能每个接口都去实现IDynamicWebApi和标记DynamicWebApi特性,所以我们需要添加一个公共接口来继承和标记该特性,这样别的方法只需要继承即可。同理我们也可能需要每个接口都要有的一些通用的方法,所以我这里还写了一个Api的基类。
给Controller项目下添加一个Core(存放基类和通用方法的)的文件夹和一个Controllers(存放接口使用的)的文件夹如下所示:
注:这里的ApiController.xml是在swagger教程里面生成注释文件教程里面自动生成的。具体如何配置生成的请点击。这个注释文件一定要在Controller上配置,这样生成的swaggerApi文档才会有我们写的注释。
在Core里面添加一个IAppService接口文件和一个AppService类文件 如图所示:
这里面我扩展了两个在DDD里面比较通用的方法,本来打算用AutoMapper的,由于测试就没去用了,做Domain和Dto之间的映射还是AutoMapper好点(有个缺点是第一次映射还没我下面写的运行速度快,但是多次映射的话AutoMapper的性能还可以)
IAppService的代码如下
using Panda.DynamicWebApi;
using Panda.DynamicWebApi.Attributes;
using System.Collections.Generic;
namespace Controller.Core
{
[DynamicWebApi]
public interface IAppService : IDynamicWebApi
{
///
/// 传入实体内容,转化为对应的Dto
///
/// 要转化的Dto类
/// 传入的实体数据
///
TDto EntityToDto(object entity) where TDto : class, new();
///
/// 传入List实体内容,转化为对应的List Dto
///
///
/// 传入的List实体数据
///
List EntityToDto(List
AppService的代码如下
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Controller.Core
{
public class AppService : IAppService
{
public AppService()
{
}
///
/// 传入实体内容,转化为对应的Dto
///
/// 要转化的Dto类
/// 传入的实体数据
///
public TDto EntityToDto(object entity) where TDto : class, new()
{
return Entitytodto(entity);
}
///
/// 传入List实体内容,转化为对应的List Dto
///
///
/// 传入的List实体数据
///
public List EntityToDto(List
之后我们把TestController类移动到Controllers文件夹下 如图:
并修改代码(这里不需要实现IDynamicWebApi和标记DynamicWebApi特性
只需要继承我们自己的AppService, IAppService)如下:
using Controller.Core;
namespace Controller.Controllers.Test
{
///
/// 测试类
///
public class TestAppService : AppService, IAppService
{
public string GetHelloWorld()
{
return "Hello World !!";
}
}
}
再次运行Api项目你可以看到Swagger上Test接口还是在的,如下:
到这里Controller从API里解耦出来已经初步经完成。
github地址:https://github.com/houliren/Asp.netcore-Code-First-DDD