ABP-Book Store Application中文讲解 - Part 6: Authors: Domain Layer
ABP-Book Store Application中文讲解 - Part 6: Authors: Domain Layer
1. 汇总
ABP-Book Store Application中文讲解-汇总-CSDN博客
2. 前一章
ABP-Book Store Application中文讲解 - Part 5: Authorization-CSDN博客
项目之间的引用关系。
BookAppService利用的是CurdAppService,里面帮我们实现了增删改查的所有方法,从本篇开始主要用于介绍手动撸代码的方式实现类似CurdAppService的方法,讲解DDD的最佳实践,权限控制利用Authorize设置。
并且介绍了哪些情况下需要用到Domain Sevice (例如判断唯一约束,一些entity的validation等),哪些情况不用Domain Serice。
目录
1. 在Domain中创建Author.cs
2. 创建Domain service (AuthorManager)
2.1 为什么需要创建Domain Service
2.2 创建IAuthorRepository
2.3 创建Error Codes
2.4 创建Business Exception - AuthorAlreadyExistsException
2.5 创建AuthorManager
3. Domain Layer目录结构
4. 继续学习
1. 在Domain中创建Author.cs
在Acme.BookStore.Domain.Shared中创建AuthorConsts.cs
namespace Acme.BookStore;public static class AuthorConsts
{public const int MaxNameLength = 64;
}
在Acme.BookStore.Domain中创建Authors目录,然后创建Author.cs,继承FullAuditedAggregateRoot.
using System;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;namespace Acme.BookStore.Authors;
public class Author : FullAuditedAggregateRoot<Guid>
{public string Name { get; private set; }public DateTime BirthDate { get; set; }/// <summary>/// 笔名?/// </summary>public string ShortBio { get; set; }private Author(){/* This constructor is for deserialization / ORM purpose */}internal Author(Guid id,string name,DateTime birthDate,string? shortBio = null): base(id){SetName(name);BirthDate = birthDate;ShortBio = shortBio;}internal Author ChangeName(string name){SetName(name);return this;}private void SetName(string name){Name = Check.NotNullOrWhiteSpace(name,nameof(name),maxLength: AuthorConsts.MaxNameLength);}
}
2. 创建Domain service (AuthorManager)
2.1 为什么需要创建Domain Service
Author
构造函数和 ChangeName
是 internal
, 他们只能被用在同一个domain layer.因此需要在 Acme.BookStore.Domain项目中的Authors文件夹中
创建 AuthorManager.cs
DDD tip: 不要引入域服务方法,除非它们确实需要并执行一些核心业务规则。对于这种情况,我们需要该服务能够强制惟一名称约束。
在创建在AuthorManager.cs之前需要一些前置条件:
2.2 创建IAuthorRepository
在Acme.BookStore.Domain的Authors目录创建IAuthorRepository.cs 接口
IAuthorRepository
扩展标准的IRepository<Author, Guid>
接口, 因此 repository 中的所有方法在IAuthorRepository中都可用
.FindByNameAsync
用于AuthorManager
根据名字查询AuthorGetListAsync
UI使用,获取用户列表、排序和过滤作者列表.
Standard Repository Methods
Generic Repositories provide some standard CRUD features out of the box:
GetAsync
: Returns a single entity by itsId
or a predicate (lambda expression).
- Throws
EntityNotFoundException
if the requested entity was not found.- Throws
InvalidOperationException
if there are multiple entities with the given predicate.FindAsync
: Returns a single entity by itsId
or a predicate (lambda expression).
- Returns
null
if the requested entity was not found.- Throws
InvalidOperationException
if there are multiple entities with the given predicate.InsertAsync
: Inserts a new entity into the database.UpdateAsync
: Updates an existing entity in the database.DeleteAsync
: Deletes the given entity from the database.
- This method has an overload that takes a predicate (lambda expression) to delete multiple entities to satisfy the given condition.
GetListAsync
: Returns the list of all entities in the database.GetPagedListAsync
: Returns a limited list of entities. GetsskipCount
,maxResultCount
, andsorting
parameters.GetCountAsync
: Gets the count of all entities in the database.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;namespace Acme.BookStore.Authors;public interface IAuthorRepository : IRepository<Author, Guid>
{Task<Author> FindByNameAsync(string name);Task<List<Author>> GetListAsync(int skipCount,int maxResultCount,string sorting,string filter = null);
}
2.3 创建Error Codes
Acme.BookStore.Domain.Shared中的BookStoreDomainErrorCodes.cs添加如下代码:
public const string AuthorAlreadyExists = "BookStore:00001";
2.4 创建Business Exception - AuthorAlreadyExistsException
创建AuthorAlreadyExistsException用于判断名字是否唯一。
需要在Acme.BookStore.Domain.Shared中的BookStoreDomainErrorCodes.cs中添加错误代码AuthorAlreadyExists
public const string AuthorAlreadyExists = "BookStore:00001";
using Volo.Abp;namespace Acme.BookStore.Authors;public class AuthorAlreadyExistsException : BusinessException
{public AuthorAlreadyExistsException(string name): base(BookStoreDomainErrorCodes.AuthorAlreadyExists){WithData("name", name);}
}
2.5 创建AuthorManager
在Acme.BookStore.Domain中创建Authors目录创建AuthorManager.cs,继承DomainService.
using System;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Domain.Services;namespace Acme.BookStore.Authors;public class AuthorManager : DomainService
{private readonly IAuthorRepository _authorRepository;public AuthorManager(IAuthorRepository authorRepository){_authorRepository = authorRepository;}public async Task<Author> CreateAsync(string name,DateTime birthDate,string? shortBio = null){Check.NotNullOrWhiteSpace(name, nameof(name));var existingAuthor = await _authorRepository.FindByNameAsync(name);if (existingAuthor != null){throw new AuthorAlreadyExistsException(name);}return new Author(GuidGenerator.Create(),name,birthDate,shortBio);}public async Task ChangeNameAsync(Author author,string newName){Check.NotNull(author, nameof(author));Check.NotNullOrWhiteSpace(newName, nameof(newName));var existingAuthor = await _authorRepository.FindByNameAsync(newName);if (existingAuthor != null && existingAuthor.Id != author.Id){throw new AuthorAlreadyExistsException(newName);}author.ChangeName(newName);}
}
3. Domain Layer目录结构
4. 继续学习
ABP-Book Store Application中文讲解 - Part 7: Authors: Database Integration-CSDN博客