ABP框架入门学习【进阶】(七)——作者模块应用层
一、创建IAuthorAppService接口
TestApp.BookStore.Application.Contracts>Authors新建接口命名为IAuthorAppService并继承IApplicationService
,脚本如下:
using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; namespace TestApp.BookStore.Authors { public interface IAuthorAppService : IApplicationService { Task<AuthorDto> GetAsync(Guid id); Task<PagedAndSortedResultRequestDto> GetListAsync(GetAuthorListDto input); Task<AuthorDto> CreateAsync(CreateAuthorDto input); Task UpdateAsync(Guid id, UpdateAuthorDto input); Task DeleteAsync(Guid id); } }
IApplicationService
是一个常规接口, 所有应用服务都继承自它, 所以 ABP 框架可以识别它们.- 在
Author
实体中定义标准方法用于CRUD操作. PagedResultDto
是一个ABP框架中预定义的 DTO 类. 它拥有一个Items
集合 和一个TotalCount
属性, 用于返回分页结果.
AuthorDto类:
using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.Application.Dtos;
namespace TestApp.BookStore.Authors
{
public class AuthorDto : EntityDto<Guid>
{
public string Name { get; set; }
public DateTime BirthDate { get; set; }
public string ShortBio { get; set; }
}
}
EntityDto<T>
只有一个类型为指定泛型参数的Id
属性. 你可以自己创建Id
属性, 而不是继承自EntityDto<T>
.
GetAuthorListDto类:
using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.Application.Dtos;
namespace TestApp.BookStore.Authors
{
public class GetAuthorListDto : PagedAndSortedResultRequestDto
{
public string Filter { get; set; }
}
}
Filter
用于搜索作者. 它可以是null
(或空字符串) 以获得所有用户.PagedAndSortedResultRequestDto
具有标准分页和排序属性:int MaxResultCount
,int SkipCount
和string Sorting
.
CreateAuthorDto 类:
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Text; namespace TestApp.BookStore.Authors { public class CreateAuthorDto { [Required] [StringLength(AuthorConsts.MaxNameLength)] public string Name { get; set; } [Required] public DateTime BirthDate { get; set; } public string ShortBio { get; set; } } }
UpdateAuthorDto 类:
using System; using System.Collections.Generic; using System.Text; using Volo.Abp.Application.Dtos; using System.ComponentModel.DataAnnotations; namespace TestApp.BookStore.Authors { public class UpdateAuthorDto { [Required] [StringLength(AuthorConsts.MaxNameLength)] public string Name { get; set; } [Required] public DateTime BirthDate { get; set; } public string ShortBio { get; set; } } }
二、创建AuthorAppService类实现IAuthorAppService接口
- 由
BookStoreAppService
派生, 这个类是一个简单基类, 可以做为模板. 它继承自标准的ApplicationService
类. - 实现上面定义的
IAuthorAppService
. - 注入
IAuthorRepository
和AuthorManager
以使用服务方法.·
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using TestApp.BookStore.Permissions; using Microsoft.AspNetCore.Authorization; using Volo.Abp.Application.Dtos; using Volo.Abp.Domain.Repositories; namespace TestApp.BookStore.Authors { [Authorize(BookStorePermissions.Authors.Default)] public class AuthorAppService : BookStoreAppService, IAuthorAppService { private readonly IAuthorRepository _authorRepository; private readonly AuthorManager _authorManager; public AuthorAppService( IAuthorRepository authorRepository, AuthorManager authorManager) { _authorRepository = authorRepository; _authorManager = authorManager; } [Authorize(BookStorePermissions.Authors.Create)] public async Task<AuthorDto> CreateAsync(CreateAuthorDto input) { var author = await _authorManager.CreateAsync( input.Name, input.BirthDate, input.ShortBio ); await _authorRepository.InsertAsync(author); return ObjectMapper.Map<Author, AuthorDto>(author); } [Authorize(BookStorePermissions.Authors.Delete)] public async Task DeleteAsync(Guid id) { await _authorRepository.DeleteAsync(id); } public async Task<AuthorDto> GetAsync(Guid id) { var author = await _authorRepository.GetAsync(id); return ObjectMapper.Map<Author, AuthorDto>(author); } public async Task<PagedResultDto<AuthorDto>> GetListAsync(GetAuthorListDto input) { if (input.Sorting.IsNullOrWhiteSpace()) { input.Sorting = nameof(Author.Name); } var authors = await _authorRepository.GetListAsync( input.SkipCount, input.MaxResultCount, input.Sorting, input.Filter ); var totalCount = input.Filter == null ? await _authorRepository.CountAsync() : await _authorRepository.CountAsync( author => author.Name.Contains(input.Filter)); return new PagedResultDto<AuthorDto>( totalCount, ObjectMapper.Map<List<Author>, List<AuthorDto>>(authors) ); } [Authorize(BookStorePermissions.Authors.Edit)] public async Task UpdateAsync(Guid id, UpdateAuthorDto input) { var author = await _authorRepository.GetAsync(id); if (author.Name != input.Name) { await _authorManager.ChangeNameAsync(author, input.Name); } author.BirthDate = input.BirthDate; author.ShortBio = input.ShortBio; await _authorRepository.UpdateAsync(author); } } }
其中会用Authorize授权,可参照之前Book授权修改:
打开 TestApp.BookStore.Application.Contracts
项目中的 BookStorePermissions
类 (在 Permissions
文件夹中), 添加为如下代码:
对象映射配置
AuthorAppService
使用 ObjectMapper
将 Author
对象 转换为 AuthorDto
对象. 所以, 我们需要在 AutoMapper 配置中定义映射.
打开 TestApp.BookStore.Application
项目中的 BookStoreApplicationAutoMapperProfile
类, 修改为:
using AutoMapper; using TestApp.BookStore.Authors; using TestApp.BookStore.Books; namespace TestApp.BookStore; public class BookStoreApplicationAutoMapperProfile : Profile { public BookStoreApplicationAutoMapperProfile() { /* You can configure your AutoMapper mapping configuration here. * Alternatively, you can split your mapping configurations * into multiple profile classes for a better organization. */ CreateMap<Book, BookDto>(); CreateMap<CreateUpdateBookDto, Book>(); CreateMap<Author, AuthorDto>(); } }
三、“作者”数据种子初始化
打开 TestApp.BookStore.Domain
项目中的 BookStoreDataSeederContributor
, 修改文件内容如下:
using System; using System.Threading.Tasks; using TestApp.BookStore.Authors; using TestApp.BookStore.Books; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories; namespace TestApp.BookStore { public class BookStoreDataSeederContributor : IDataSeedContributor, ITransientDependency { private readonly IRepository<Book, Guid> _bookRepository; private readonly IAuthorRepository _authorRepository; private readonly AuthorManager _authorManager; public BookStoreDataSeederContributor(IRepository<Book, Guid> bookRepository, IAuthorRepository authorRepository, AuthorManager authorManager) { _bookRepository = bookRepository; _authorRepository = authorRepository; _authorManager = authorManager; } public async Task SeedAsync(DataSeedContext context) { // ADDED SEED DATA FOR BOOKS if (await _bookRepository.GetCountAsync() <= 0) { await _bookRepository.InsertAsync( new Book { Name = "1984", Type = BookType.Dystopia, PublishDate = new DateTime(1949, 6, 8), Price = 19.84f }, autoSave: true ); await _bookRepository.InsertAsync( new Book { Name = "The Hitchhiker's Guide to the Galaxy", Type = BookType.ScienceFiction, PublishDate = new DateTime(1995, 9, 27), Price = 42.0f }, autoSave: true ); } // ADDED SEED DATA FOR AUTHORS if (await _authorRepository.GetCountAsync() <= 0) { await _authorRepository.InsertAsync( await _authorManager.CreateAsync( "George Orwell", new DateTime(1903, 06, 25), "Orwell produced literary criticism and poetry, fiction and polemical journalism; and is best known for the allegorical novella Animal Farm (1945) and the dystopian novel Nineteen Eighty-Four (1949)." ) ); await _authorRepository.InsertAsync( await _authorManager.CreateAsync( "Douglas Adams", new DateTime(1952, 03, 11), "Douglas Adams was an English author, screenwriter, essayist, humorist, satirist and dramatist. Adams was an advocate for environmentalism and conservation, a lover of fast cars, technological innovation and the Apple Macintosh, and a self-proclaimed 'radical atheist'." ) ); } } } }
由于数据表结构和初始化数据调整,所以需要更新下数据库,将TestApp.BookStore.DbMigrator应用程序设为启动项目,
来更新数据库,运行完成会发现数据库AppAuthor表会多两条默认数据,如下图:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架