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


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

摘要:基於ASP.NET Core 3.1 WebApi搭建后端多層網站架構【8.3-編寫角色業務的增刪改】
編寫最簡單的增刪改業務,涉及到DI依賴注入的使用、AutoMapper的使用、工作單元與倉儲的使用、雪花Id的生成

文章目錄

此分支項目代碼

本章節介紹了編寫最簡單的增刪改查業務,涉及到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.csRoleService.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接口,然后使用快速操作生成構造函數和實現接口

接下來開始實現新增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調試接口:

可以看到接口調用成功(也可以看到在控制台中有EntityFrameworkCore執行的sql語句)
在數據庫中看到新增的記錄:

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

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

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 });
        }
    }
}

更新接口測試:

刪除接口測試:

項目完成后,如下圖所示


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM