【二】Asp.Netcore使用Panda.DynamicWebApi来进行Controller解耦@Asp.netcore Code First +DDD学习笔记

在Asp.Netcore内Panda.DynamicWebApi的使用方法,以及如何使用Panda.DynamicWebApi来使Controller何Server解耦

 

主题:Asp.netcore Code First +DDD学习笔记

目录:

   【一】 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,如图所示:

【二】Asp.Netcore使用Panda.DynamicWebApi来进行Controller解耦@Asp.netcore Code First +DDD学习笔记_第1张图片

 (2)在Api项目上注入该组件。

          删除Api上面的Controller文件夹,使Api项目如下图所示 

         【二】Asp.Netcore使用Panda.DynamicWebApi来进行Controller解耦@Asp.netcore Code First +DDD学习笔记_第2张图片   

         在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的测试类

   【二】Asp.Netcore使用Panda.DynamicWebApi来进行Controller解耦@Asp.netcore Code First +DDD学习笔记_第3张图片

  代码如下:

using Panda.DynamicWebApi;
using Panda.DynamicWebApi.Attributes;

namespace Controller
{
    [DynamicWebApi]
    public class TestController : IDynamicWebApi
    {
        public string GetHelloWorld()
        {
            return "Hello World !!";
        }
    }
}

  启动Api项目,将会在Swagger上看到该接口,如图:

【二】Asp.Netcore使用Panda.DynamicWebApi来进行Controller解耦@Asp.netcore Code First +DDD学习笔记_第4张图片

   (3)在上面的这些步骤,我们完成Controller的解耦,Controller的代码可以写在别的项目了,而主项目只需要添加对该项目的引用即可,在为了方便,我们不能每个接口都去实现IDynamicWebApi标记DynamicWebApi特性,所以我们需要添加一个公共接口来继承和标记该特性,这样别的方法只需要继承即可。同理我们也可能需要每个接口都要有的一些通用的方法,所以我这里还写了一个Api的基类。

 给Controller项目下添加一个Core(存放基类和通用方法的)的文件夹和一个Controllers(存放接口使用的)的文件夹如下所示:

注:这里的ApiController.xml是在swagger教程里面生成注释文件教程里面自动生成的。具体如何配置生成的请点击。这个注释文件一定要在Controller上配置,这样生成的swaggerApi文档才会有我们写的注释。

   在Core里面添加一个IAppService接口文件和一个AppService类文件 如图所示:

【二】Asp.Netcore使用Panda.DynamicWebApi来进行Controller解耦@Asp.netcore Code First +DDD学习笔记_第5张图片

这里面我扩展了两个在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 entityList) where TDto : class, new();
    }
}
 
  

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 entityList) where TDto : class, new()
        {
            List list = new List();
            foreach (var childObject in entityList)
            {
                list.Add(Entitytodto(childObject));
            }
            return list;
        }

        /// 
        /// 传入实体内容,转化为对应的Dto
        /// 
        /// 
        /// 
        /// 
        private TDto Entitytodto(object entity) where TDto : class, new()
        {
            TDto dto = new TDto();
            PropertyInfo[] propertyInfos = entity.GetType().GetProperties();
            PropertyInfo[] dtoproperty = dto.GetType().GetProperties();
            for (int i = 0; i < propertyInfos.Length; i++)
            {
                for (int j = 0; j < dtoproperty.Length; j++)
                {
                    if (propertyInfos[i].Name == dtoproperty[j].Name)
                    {
                        dtoproperty[j].SetValue(dto, propertyInfos[i].GetValue(entity));
                        break;
                    }
                }
            }
            return dto;
        }
    }
}
 
  

之后我们把TestController类移动到Controllers文件夹下 如图:

【二】Asp.Netcore使用Panda.DynamicWebApi来进行Controller解耦@Asp.netcore Code First +DDD学习笔记_第6张图片

并修改代码(这里不需要实现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接口还是在的,如下:

【二】Asp.Netcore使用Panda.DynamicWebApi来进行Controller解耦@Asp.netcore Code First +DDD学习笔记_第7张图片

到这里Controller从API里解耦出来已经初步经完成。

github地址:https://github.com/houliren/Asp.netcore-Code-First-DDD

你可能感兴趣的:(Asp.netcore,DDD,EfCore)