天天看點

ASP.NET Core搭建多層網站架構【8.3-編寫角色業務的增删改】

基于ASP.NET Core 3.1 WebApi搭建後端多層網站架構【8.3-編寫角色業務的增删改】

編寫最簡單的增删改業務,涉及到DI依賴注入的使用、AutoMapper的使用、工作單元與倉儲的使用、雪花Id的生成

2020/01/29, ASP.NET Core 3.1, VS2019

摘要:基于ASP.NET Core 3.1 WebApi搭建後端多層網站架構【8.3-編寫角色業務的增删改】

文章目錄

此分支項目代碼

本章節介紹了編寫最簡單的增删改查業務,涉及到DI依賴注入的使用、AutoMapper的使用、工作單元與倉儲的使用

類庫添加引用

MS.Services

類庫添加對

MS.Models

項目的引用

BaseService

MS.Services

類庫中添加

BaseService.cs

類:

using AutoMapper;
using MS.Common.IDCode;
using MS.DbContexts;
using MS.UnitOfWork;

namespace MS.Services
{
    public interface IBaseService
    {
    }
    public class BaseService : IBaseService
    {
        public readonly IUnitOfWork<MSDbContext> _unitOfWork;
        public readonly IMapper _mapper;
        public readonly IdWorker _idWorker;

        public BaseService(IUnitOfWork<MSDbContext> unitOfWork, IMapper mapper, IdWorker idWorker)
        {
            _unitOfWork = unitOfWork;
            _mapper = mapper;
            _idWorker = idWorker;
        }
    }
}
           

說明:

  • 建立了IBaseService接口,後面建立的服務接口都要繼承自該接口
  • 建立了BaseService類,實作了IBaseService接口
  • 可以看到BaseService類中,使用構造函數的方式依賴注入得到了IUnitOfWork _unitOfWork、IMapper _mapper、IdWorker _idWorker,并且是public類型,是以繼承BaseService的類都可以直接使用父類的這三個成員

RoleService

MS.Services

類庫中建立Role檔案夾,在該檔案夾下建立

IRoleService.cs

RoleService.cs

類,注意我這裡兩個類的命名空間都改為

namespace MS.Services

,而不是預設的

namespace MS.Services.Role

IRoleService接口

修改IRoleService為public類型的interface接口,繼承自IBaseService,并添加Create、Update、Delete三個方法:

using MS.Entities;
using MS.Models.ViewModel;
using MS.WebCore.Core;
using System.Threading.Tasks;

namespace MS.Services
{
    public interface IRoleService : IBaseService
    {
        Task<ExecuteResult<Role>> Create(RoleViewModel viewModel);
        Task<ExecuteResult> Update(RoleViewModel viewModel);
        Task<ExecuteResult> Delete(RoleViewModel viewModel);
    }
}
           

RoleService實作

修改RoleService為public類型,繼承自BaseService和IRoleService接口,然後使用快速操作生成構造函數和實作接口

ASP.NET Core搭建多層網站架構【8.3-編寫角色業務的增删改】

接下來開始實作新增Role的業務方法:

public async Task<ExecuteResult<Role>> Create(RoleViewModel viewModel)
{
    ExecuteResult<Role> result = new ExecuteResult<Role>();
    //檢查字段
    if (viewModel.CheckField(ExecuteType.Create, _unitOfWork) is ExecuteResult checkResult && !checkResult.IsSucceed)
    {
        return result.SetFailMessage(checkResult.Message);
    }
    using (var tran = _unitOfWork.BeginTransaction())//開啟一個事務
    {
        Role newRow = _mapper.Map<Role>(viewModel);
        newRow.Id = _idWorker.NextId();//擷取一個雪花Id
        newRow.Creator = 1219490056771866624;//由于暫時還沒有做登入,是以拿不到登入者資訊,先随便寫一個後面再完善
        newRow.CreateTime = DateTime.Now;
        _unitOfWork.GetRepository<Role>().Insert(newRow);
        await _unitOfWork.SaveChangesAsync();
        await tran.CommitAsync();//送出事務

        result.SetData(newRow);//添加成功,把新的實體傳回回去
    }
    return result;
}
           
  • 異步方法要加上async标記
  • 執行添加之前,先進行了字段檢查,如果不通過,則傳回錯誤資訊
  • 使用了var tran = _unitOfWork.BeginTransaction()開啟了事務,如果遇到異常,會自動復原,如果不需要使用事務,可以去除,這裡隻是順帶示範下事務的使用方法
  • 使用了_mapper.Map方法把字段從ViewModel映射到實體類中
  • _idWorker.NextId()方法擷取一個雪花Id
  • 由于還沒有做登入,是以沒有建立者資訊,是以先随便寫了一個,等做了登入之後再修改
  • 這裡方法内部沒有做trycatch捕獲異常處理,之後會使用AOP攔截器,攔截業務層的每個方法,統一進行業務異常捕獲處理

WebApi中調用Service

MS.WebApi

應用程式中,

RoleController.cs

類中,添加RoleService接口,并在Post中調用Create方法:

//using MS.Services;
//以上代碼添加到using引用
public class RoleController : ControllerBase
{
    private readonly IRoleService _roleService;

    public RoleController(IRoleService roleService)
    {
        _roleService = roleService;
    }

    [HttpPost]
    public async Task<ExecuteResult> Post(RoleViewModel viewModel)
    {
        return await _roleService.Create(viewModel);
    }
}
           
  • 這裡依然使用了構造函數依賴注入擷取一個接口服務
  • 接口設計滿足Restful規範

将接口服務添加到依賴注入

MS.WebApi

應用程式中,在

Startup.cs

類的ConfigureServices方法中追加:

//using MS.Services;
//以上代碼添加到using
//注冊IBaseService和IRoleService接口及對應的實作類
services.AddScoped<IBaseService, BaseService>();
services.AddScoped<IRoleService, RoleService>();
           

測試

完成後啟動項目,打開Postman調試接口:

ASP.NET Core搭建多層網站架構【8.3-編寫角色業務的增删改】

可以看到接口調用成功(也可以看到在控制台中有EntityFrameworkCore執行的sql語句)

在資料庫中看到新增的記錄:

ASP.NET Core搭建多層網站架構【8.3-編寫角色業務的增删改】

再重複調用一次接口,則會提示角色名稱已存在:

ASP.NET Core搭建多層網站架構【8.3-編寫角色業務的增删改】

完整的增删改角色業務代碼:

using AutoMapper;
using MS.Common.IDCode;
using MS.DbContexts;
using MS.Entities;
using MS.Models.ViewModel;
using MS.UnitOfWork;
using MS.WebCore.Core;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace MS.Services
{
    public class RoleService : BaseService, IRoleService
    {
        public RoleService(IUnitOfWork<MSDbContext> unitOfWork, IMapper mapper, IdWorker idWorker) : base(unitOfWork, mapper, idWorker)
        {
        }

        public async Task<ExecuteResult<Role>> Create(RoleViewModel viewModel)
        {
            ExecuteResult<Role> result = new ExecuteResult<Role>();
            //檢查字段
            if (viewModel.CheckField(ExecuteType.Create, _unitOfWork) is ExecuteResult checkResult && !checkResult.IsSucceed)
            {
                return result.SetFailMessage(checkResult.Message);
            }
            using (var tran = _unitOfWork.BeginTransaction())//開啟一個事務
            {
                Role newRow = _mapper.Map<Role>(viewModel);
                newRow.Id = _idWorker.NextId();//擷取一個雪花Id
                newRow.Creator = 1219490056771866624;//由于暫時還沒有做登入,是以拿不到登入者資訊,先随便寫一個後面再完善
                newRow.CreateTime = DateTime.Now;
                _unitOfWork.GetRepository<Role>().Insert(newRow);
                await _unitOfWork.SaveChangesAsync();
                await tran.CommitAsync();//送出事務

                result.SetData(newRow);//添加成功,把新的實體傳回回去
            }
            return result;
        }

        public async Task<ExecuteResult> Delete(RoleViewModel viewModel)
        {
            ExecuteResult result = new ExecuteResult();
            //檢查字段
            if (viewModel.CheckField(ExecuteType.Delete, _unitOfWork) is ExecuteResult checkResult && !checkResult.IsSucceed)
            {
                return checkResult;
            }
            _unitOfWork.GetRepository<Role>().Delete(viewModel.Id);
            await _unitOfWork.SaveChangesAsync();//送出
            return result;
        }

        public async Task<ExecuteResult> Update(RoleViewModel viewModel)
        {
            ExecuteResult result = new ExecuteResult();
            //檢查字段
            if (viewModel.CheckField(ExecuteType.Update, _unitOfWork) is ExecuteResult checkResult && !checkResult.IsSucceed)
            {
                return checkResult;
            }

            //從資料庫中取出該記錄
            var row = await _unitOfWork.GetRepository<Role>().FindAsync(viewModel.Id);//在viewModel.CheckField中已經擷取了一次用于檢查,是以此處不會重複再從資料庫取一次,有緩存
            //修改對應的值
            row.Name = viewModel.Name;
            row.DisplayName = viewModel.DisplayName;
            row.Remark = viewModel.Remark;
            row.Modifier = 1219490056771866624;//由于暫時還沒有做登入,是以拿不到登入者資訊,先随便寫一個後面再完善
            row.ModifyTime = DateTime.Now;
            _unitOfWork.GetRepository<Role>().Update(row);
            await _unitOfWork.SaveChangesAsync();//送出

            return result;
        }
    }
}

           

完整的接口代碼:

using Microsoft.AspNetCore.Mvc;
using MS.Models.ViewModel;
using MS.Services;
using MS.WebCore.Core;
using System.Threading.Tasks;

namespace MS.WebApi.Controllers
{
    [Route("[controller]")]
    [ApiController]
    public class RoleController : ControllerBase
    {
        private readonly IRoleService _roleService;

        public RoleController(IRoleService roleService)
        {
            _roleService = roleService;
        }

        [HttpPost]
        public async Task<ExecuteResult> Post(RoleViewModel viewModel)
        {
            return await _roleService.Create(viewModel);
        }

        [HttpPut]
        public async Task<ExecuteResult> Put(RoleViewModel viewModel)
        {
            return await _roleService.Update(viewModel);
        }

        [HttpDelete]
        public async Task<ExecuteResult> Delete(long id)
        {
            return await _roleService.Delete(new RoleViewModel { Id = id });
        }
    }
}
           

更新接口測試:

ASP.NET Core搭建多層網站架構【8.3-編寫角色業務的增删改】

删除接口測試:

ASP.NET Core搭建多層網站架構【8.3-編寫角色業務的增删改】

項目完成後,如下圖所示

ASP.NET Core搭建多層網站架構【8.3-編寫角色業務的增删改】
ASP.NET Core搭建多層網站架構【8.3-編寫角色業務的增删改】

繼續閱讀