Skip to content

Latest commit

 

History

History
668 lines (519 loc) · 18.1 KB

4.DevProcess.md

File metadata and controls

668 lines (519 loc) · 18.1 KB

开发流程

通过一个demo进行开发流程的详细讲解,并且演示如何在满足规范的前提下书写业务,操作DB,使用框架方法以及日志,异常,事务等的处理。

4.1 demo场景描述

此场景中,我们会创建一个Test_Demo的表,并且包含Id,Name,Number和Email字段,并创建查询,追加,删除,更新等常规操作。

4.2 目录说明

Services

DebtBase

NGP.DebtBase.Api: 债务基础api

App_Data 应用数据文件夹

XmlDocuments dll编译的xml文件用于生成swagger帮助文档

Controllers 控制器文件夹

appsettings.json 应用配置说明参照:[2.3.1](### 2.3.1、appsettings.json)

dockerfile 容器部署文件,相关说明参照:[5.5.2](### 5.5.2)

log4net.config log4net配置文件

Program.cs 程序启动入口

Startup.cs 程序启动类

NGP.DebtBase.Domain 债务基础业务dll

DebtBaseResource.resx 债务基础相关消息定义

DebtBaseDbInit 债务基础api启动时需要进行的数据库初始化处理

DebtBaseDependencyRegistrar:债务基础业务统一注入类

DebtBaseConst:常量定义

CurrentVersion 当前版本

4.3 demo书写

4.3.1 创建相关文件

  • 在src/Services/DebtBase/NGP.DebtBase.Api/Controllers 下创建 DemoController.cs文件

  • 在src/Services/DebtBase/NGP.DebtBase.Domain/ 根据以下结构创建文件

Demo : 场景业务单元文件夹

Models :存放相关模型

ApiDto : 存放api请求的requestresponse对象,分别是:

CreateDemoRequest

QueryDemoRequest

QueryDemoResponse

UpdateDemoRequest

Entities :存放数据库对应的实体对象

Test_Demo

Validation :存放api请求时的验证模型,分别是:

CreateDemoRequestValidator

QueryDemoRequestValidator

UpdateDemoRequestValidator

Maps :存放DB映射和模型映射

DemoModelMapProfile :模型映射文件

Test_DemoMap : 实体映射文件

IDemoService :场景业务接口

DemoService :场景业务实现

4.3.2 在创建的文件里添加实现

  • 首先添加DB实体

    • Test_Demo

    • 业务表都需要继承BaseDBEntity

    • 其代码如下:

/* ---------------------------------------------------------------------
 * Copyright:
 * IXinWu Technology Co., Ltd. All rights reserved.
 *
 * Test_Demo Description:
 * 测试模型
 *
 * Comment                          Revision    Date        Author
 * -----------------------------    --------    --------    -----------
 * Created                          1.0         2019-8-25   [email protected]
 *
 * ------------------------------------------------------------------------------*/

using NGP.Framework.Core;

namespace NGP.DebtBase.Domain.Demo
{
    /// <summary>
    /// 测试模型
    /// </summary>
    public class Test_Demo : BaseDBEntity
    {
        /// <summary>
        /// name
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// number
        /// </summary>
        public int Number { get; set; }

        /// <summary>
        /// email
        /// </summary>
        public string Email { get; set; }
    }
}
  • 添加DB映射

    • Test_DemoMap :

    • 继承BaseDBEntity的表映射必须继承BaseDBEntityMap<T>

    • 重写Configure方法

      • 其代码如下:
/* ---------------------------------------------------------------------
 * Copyright:
 * IXinWu Technology Co., Ltd. All rights reserved.
 *
 * Test_DemoMap Description:
 * demo实体映射
 *
 * Comment                          Revision    Date        Author
 * -----------------------------    --------    --------    -----------
 * Created                          1.0         2019-8-27   [email protected]
 *
 * ------------------------------------------------------------------------------*/

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using NGP.Framework.Core.Data;

namespace NGP.DebtBase.Domain.Demo
{
    /// <summary>
    /// demo实体映射
    /// </summary>
    public class Test_DemoMap: BaseDBEntityMap<Test_Demo>
    {
        /// <summary>
        /// 映射配置
        /// </summary>
        /// <param name="builder"></param>
        public override void Configure(EntityTypeBuilder<Test_Demo> builder)
        {
            builder.ToTable(nameof(Test_Demo));
            builder.Property(store => store.Name).HasMaxLength(200).IsRequired();
            builder.Property(store => store.Number).IsRequired();
            builder.Property(store => store.Email).HasMaxLength(500);
            base.Configure(builder);
        }
    }
}
  • 添加api请求和返回模型

    • CreateDemoRequest

      • 对象必须继承:INGPModel

      • 代码见下

    • QueryDemoRequest 参照:CreateDemoRequest,实现省略

    • UpdateDemoRequest 参照:CreateDemoRequest,实现省略

    • QueryDemoResponse, 实现省略

/* ---------------------------------------------------------------------
 * Copyright:
 * IXinWu Technology Co., Ltd. All rights reserved.
 *
 * CreateDemoRequest Description:
 * 创建demo请求对象
 *
 * Comment                          Revision    Date        Author
 * -----------------------------    --------    --------    -----------
 * Created                          1.0         2019-8-27   [email protected]
 *
 * ------------------------------------------------------------------------------*/

using NGP.Framework.Core;
using System.Runtime.Serialization;

namespace NGP.DebtBase.Domain.Demo
{
  /// <summary>
  /// 创建demo请求对象
  /// </summary>
  public class CreateDemoRequest : INGPModel
  {
    /// <summary>
    /// name
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// number
    /// </summary>
    public int Number { get; set; }

    /// <summary>
    /// email
    /// </summary>
    public string Email { get; set; }
  }
}
  • 定义验证模型

    • CreateDemoRequestValidator

      • 验证对象必须继承BaseNGPValidator<T>,此处TCreateDemoRequest

      • 在构造函数使用RuleFor添加对应的规则,代码见下

    • QueryDemoRequestValidator

      • 实现省略
    • UpdateDemoRequestValidator

      • 如果发现验证重复但是属于不同的模型,可采用抽取共同的方法或者继承的方法进行重构

      • 实现省略

/* ---------------------------------------------------------------------
 * Copyright:
 * IXinWu Technology Co., Ltd. All rights reserved.
 *
 * CreateDemoRequestValidator Description:
 * 创建对象请求验证模型
 *
 * Comment                          Revision    Date        Author
 * -----------------------------    --------    --------    -----------
 * Created                          1.0         2019-8-27   [email protected]
 *
 * ------------------------------------------------------------------------------*/

using FluentValidation;
using NGP.Framework.Core;

namespace NGP.DebtBase.Domain.Demo
{
    /// <summary>
    /// 创建对象请求验证模型
    /// </summary>
    public class CreateDemoRequestValidator : BaseNGPValidator<CreateDemoRequest>
    {
        /// <summary>
        /// ctor
        /// </summary>
        public CreateDemoRequestValidator()
        {
            RuleFor(x => x.Name)
                .NotEmpty()
                .WithStatusCode(StatusCode.EmptyError,"名称")
                .MaximumLength(20)
                .WithStatusCode(StatusCode.MaxLengthError,"名称",20);

            RuleFor(x => x.Number)
                .NotEmpty()
                .WithStatusCode(StatusCode.EmptyError, "数字")
                .Must(x => x > 10 && x < 50)
                .WithStatusCode(StatusCode.BetweenValueError, "数字", 10,50);

            RuleFor(x => x.Email)
                .Must(x =>
                {
                    if (string.IsNullOrWhiteSpace(x))
                    {
                        return true;
                    }
                    return CommonHelper.IsValidEmail(x);
                })
                .WithStatusCode(StatusCode.FormatError, "邮件", "[email protected]");
        }
    }
}
  • 定义模型映射

    • DemoModelMapProfile

      • 必须继承:Profile, INGPMapperProfile

      • 在构造函数创建模型映射

      • 代码如下:

/* ---------------------------------------------------------------------
 * Copyright:
 * IXinWu Technology Co., Ltd. All rights reserved.
 *
 * DemoModelMapProfile Description:
 * demo 模型映射
 *
 * Comment                          Revision    Date        Author
 * -----------------------------    --------    --------    -----------
 * Created                          1.0         2019-8-27   [email protected]
 *
 * ------------------------------------------------------------------------------*/

using AutoMapper;
using NGP.Framework.Core.Infrastructure;

namespace NGP.DebtBase.Domain.Demo
{
    /// <summary>
    /// demo 模型映射
    /// </summary>
    public class DemoModelMapProfile: Profile, INGPMapperProfile
    {
        /// <summary>
        /// ctor
        /// </summary>
        public DemoModelMapProfile()
        {
            CreateMap<Test_Demo, QueryDemoResponse>();

            CreateMap<CreateDemoRequest, Test_Demo>();
        }

        #region Properties

        /// <summary>
        /// Order of this mapper implementation
        /// </summary>
        public int Order => 1;

        #endregion
    }
}
  • 定义业务接口

    • IDemoService

      • 添加对应的接口方法,

      • 如果是分页查询接口,则:

        • 请求参数为NGPPageQueryRequest<T>,其中T为当前业务请求对象,此处为QueryDemoRequest

        • 返回参数自行定义,可以是模型,也可以是元祖对象()

      • 如果是非分页查询接口,则:

        • 请求对象为定义的XxxRequest对象
      • 补充注释后代码如下:

/* ---------------------------------------------------------------------
 * Copyright:
 * IXinWu Technology Co., Ltd. All rights reserved.
 *
 * IDemoService Description:
 * deme business interface
 *
  * Comment                          Revision    Date        Author
 * -----------------------------    --------    --------    -----------
 * Created                          1.0         2019-8-27   [email protected]
 *
 * ------------------------------------------------------------------------------*/

using NGP.Framework.Core.Models;
using System.Collections.Generic;

namespace NGP.DebtBase.Domain.Demo
{
    /// <summary>
    /// deme business interface
    /// </summary>
    public interface IDemoService
    {
        /// <summary>
        /// page query demo data
        /// </summary>
        /// <param name="request">request info</param>
        /// <returns>totalCount data</returns>
        (int totalCount, List<QueryDemoResponse> data) Query(NGPPageQueryRequest<QueryDemoRequest> request);

        /// <summary>
        /// crate demo
        /// </summary>
        /// <param name="request">request info</param>
        /// <returns>create count</returns>
        int Create(CreateDemoRequest request);

        /// <summary>
        /// update demo
        /// </summary>
        /// <param name="request">update info</param>
        /// <returns>update count</returns>
        int Update(UpdateDemoRequest request);

        /// <summary>
        /// delete demo
        /// </summary>
        /// <param name="request">delete info</param>
        /// <returns>delete count</returns>
        int Delete(NGPSingleRequest<List<string>> request);
    }
}
  • 书写api控制器

    • DemoController

      • 添加构造函数并注入IDemoService

      • 添加Query,Create,Update,Delete方法

      • 代码如下:

/* ---------------------------------------------------------------------
 * Copyright:
 * IXinWu Technology Co., Ltd. All rights reserved.
 *
 * DemoController Description:
 * demo控制器
 *
 * Comment                          Revision    Date        Author
 * -----------------------------    --------    --------    -----------
 * Created                          1.0         2019-8-27   [email protected]
 *
 * ------------------------------------------------------------------------------*/

using Microsoft.AspNetCore.Mvc;
using NGP.DebtBase.Domain.Demo;
using NGP.Framework.Core.Models;
using System.Collections.Generic;

namespace NGP.DebtBase.Api.Controllers
{
    /// <summary>
    /// demo控制器
    /// </summary>
    public class DemoController : BaseApiController
    {
        /// <summary>
        /// 服务接口
        /// </summary>
        private readonly IDemoService _demoService;

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="demoService"></param>
        public DemoController(IDemoService demoService)
        {
            _demoService = demoService;
        }

        /// <summary>
        /// page query demo data
        /// </summary>
        /// <param name="request">request info</param>
        /// <returns>query result data</returns>
        [HttpPost("query")]
        public ActionResult<NGPDataPageResponse<QueryDemoResponse>> Query(NGPPageQueryRequest<QueryDemoRequest> request)
        {
            var queryResult = _demoService.Query(request);
            return OkPageDataResult(queryResult.totalCount, queryResult.data);
        }

        /// <summary>
        /// crate demo
        /// </summary>
        /// <param name="request">request info</param>
        /// <returns>create result</returns>
        [HttpPost("create")]
        public ActionResult<NGPDataResponse<int>> Create(CreateDemoRequest request)
        {
            return OkDataResult(_demoService.Create(request));
        }

        /// <summary>
        /// update demo
        /// </summary>
        /// <param name="request">update info</param>
        /// <returns>update result</returns>
        [HttpPost("update")]
        public ActionResult<NGPDataResponse<int>> Update(UpdateDemoRequest request)
        {
            return OkDataResult(_demoService.Update(request));
        }

        /// <summary>
        /// delete demo
        /// </summary>
        /// <param name="request">delete info</param>
        /// <returns>delete result</returns>
        [HttpPost("delete")]
        public ActionResult<NGPDataResponse<int>> Delete(NGPSingleRequest<List<string>> request)
        {
            return OkDataResult(_demoService.Delete(request));
        }
    }
}
  • 添加具体业务实现

    • DemoService

      • 定义和在构造函数注入需要的接口,本业务会使用:

        • IUnitRepository使用EF操作DB的仓储
      • 模型的验证都交给对应的Validator进行处理,所以方法内不需要进行验证,额外的业务处理请无视此规则

      • 使用模型映射时,需要添加using NGP.Framework.Core;命名空间,使用.Map<T>扩展方法

/* ---------------------------------------------------------------------
 * Copyright:
 * IXinWu Technology Co., Ltd. All rights reserved.
 *
 * DemoService Description:
 * deme business implementation
 *
 * Comment                          Revision    Date        Author
 * -----------------------------    --------    --------    -----------
 * Created                          1.0         2019-8-27   [email protected]
 *
 * ------------------------------------------------------------------------------*/

using NGP.Framework.Core;
using NGP.Framework.Core.Models;
using System.Collections.Generic;
using System.Linq;


namespace NGP.DebtBase.Domain.Demo
{
    /// <summary>
    /// deme business implementation
    /// </summary>
    public class DemoService : IDemoService
    {
        /// <summary>
        /// ef上下文仓储
        /// </summary>
        private readonly IUnitRepository _unitRepository;

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="unitRepository"></param>
        public DemoService(IUnitRepository unitRepository)
        {
            _unitRepository = unitRepository;
        }

        /// <summary>
        /// page query demo data
        /// </summary>
        /// <param name="request">request info</param>
        /// <returns>query result data</returns>
        public (int totalCount, List<QueryDemoResponse> data) Query(NGPPageQueryRequest<QueryDemoRequest> request)
        {
            var criteria = new QueryCondition<Test_Demo>(s => s.IsDelete == false &&
             s.Name.Contains(request.RequestData.Name));
            var query = _unitRepository.All(criteria.Where).Select(s=>s.ToModel< QueryDemoResponse>());

            var result = query.ParsePageQuery(request);
            return result;
        }

        /// <summary>
        /// crate demo
        /// </summary>
        /// <param name="request">request info</param>
        /// <returns>create result</returns>
        public int Create(CreateDemoRequest request)
        {
            var entity = request.ToEntity<Test_Demo>();
            entity.InitAddDefaultFields();

            _unitRepository.Insert(entity);
            return _unitRepository.SaveChanges();
        }

        /// <summary>
        /// update demo
        /// </summary>
        /// <param name="request">update info</param>
        /// <returns>update result</returns>
        public int Update(UpdateDemoRequest request)
        {
            var entity = _unitRepository.FindById<Test_Demo>(request.Id);

            if (entity == null)
            {
                throw new NGPException(StatusCode.DBNotExistError);
            }
            entity.InitUpdateDefaultFields();
            entity.Name = request.Name;
            entity.Email = request.Email;
            entity.Number = request.Number;

            _unitRepository.Update(entity);
            return _unitRepository.SaveChanges();
        }

        /// <summary>
        /// delete demo
        /// </summary>
        /// <param name="request">delete info</param>
        /// <returns>delete result</returns>
        public int Delete(NGPSingleRequest<List<string>> request)
        {
            return _unitRepository.BatchDelete<Test_Demo>(s => request.RequestData.Contains(s.Id));
        }
    }
}
  • 至此一个简单的demo完成,后续持续添加

返回