其他分享
首页 > 其他分享> > 基于ABP实现DDD--领域逻辑和应用逻辑

基于ABP实现DDD--领域逻辑和应用逻辑

作者:互联网

  本文主要介绍了多应用层的问题,包括原因和实现。通过理解介绍了如何区分领域逻辑和应用逻辑,哪些是正确的实践,哪些是不推荐的或者错误的实践。

一.多应用层的问题

1.多应用层介绍

  不知道你们是否会遇到一种情况,通过ABP构建了一个后端的API项目,刚开始是为Web端项目(比如,Vue)提供后端接口服务的,随着项目的发展和业务的复杂,增加了移动端的App,或者公众号、小程序等,这样不仅要为Web端提供API服务,而且还需要为移动端的App,或者公众号、小程序等提供API服务。这个场景就是多应用层的问题。也就是说你现在需要构建一个有多个应用程序的系统了:

2.多应用层例子

  由于业务的复杂性,每个应用系统都有自己的不同应用服务方法,不同的输入和输出DTO,不用的认证和授权规则等,所以如果把所有的业务逻辑都融入到一个应用系统中,就会让系统更难开发、维护和测试,并导致潜在的Bug风险。因此,为每个应用程序创建单独的应用层,并且它们都是用单个领域层来共享核心领域逻辑。为了更加具体的说明,为每种应用程序类型创建不同的.csproj项目:

二.如何区分领域逻辑和应用逻辑

通常,DDD中的业务逻辑包括领域逻辑和应用逻辑。领域逻辑由系统的核心领域规则组成,而应用程序逻辑实现特定于应用程序的用例。话虽这样说,但是并不容易区分什么是领域逻辑和应用逻辑。

1.在领域服务层中创建组织Organization

下面通过在领域服务中创建Organization这个例子,来尽可能简要说明:

public class OrganizationManager:DomainService
{
    private readonly IRepository<Organization> _organizationRepository; //Organization的仓储
    private readonly ICurrentUser _currentUser; //当前用户
    private readonly IAuthorizationService _authorizationService; //Authorization的服务
    private readonly IEmailSender _emailSender; //邮件发送服务
    
    // 公共构造函数,依赖注入
    public OrganizationManager(IRepository<Organization> organizationRepository, ICurrentUser currentUser, IAuthorizationService authorizationService, IEmailSender emailSender)
    {
        _organizationRepository=organizationRepository;
        _currentUser=currentUser;
        _authorizationService=authorizationService;
        _emailSender=emailSender;
    }
    
    // 创建一个新的组织
    public async Task<Organization> CreateAsync(string name)
    {
        // 如果组织存在同名,那么抛出异常[正确]
        if(await _organizationRepository.AnyAsync(x=>x.Name==name))
        {
            throw new BusinessException("IssueTracking:DuplicateOrganizationName");
        }
        
        // 检查是否拥有创建的权限[错误]
        await _authorizationService.CheckAsync("OrganizationCreationPermission");
        
        // 记录⽇志[错误]
        Logger.LogDebug($"Creating organization {name} by {_currentUser.UserName}");
        
        // 创建一个新的组织
        var organization = new Organization();
        
        // 发送邮件进行提醒[错误]
        await _emailSender.SendAsync("systemadmin@issuetracking.com", "新组织", "新组织名称:"+name);
        
        // 返回一个组织实例
        return organization;
    }
}

2.在应用层中使用领域服务创建组织Organization

public class OrganizationAppService:ApplicationService
{
    private readonly OrganizationManager _organizationManager; //组织的领域服务
    private readonly IPaymentService _paymentService; //支付服务
    private readonly IEmailSender _emailSender; //邮件服务
    
    // 公共构造函数,依赖注入
    public OrganizaitonAppService(OrganizationManager organizationManager, IPaymentService paymentService, IEmailSender emailSender)
    {
        _organizationManager=organizationManager;
        _paymentService=paymentService;
        _emailSender=emailSender;
    }
    
    // 创建组织
    [UnitOfWork][正确] //工作单元,用于提交事务
    [Authorize("OrganizationCreationPermission")][正确]
    public async Task<Organization> CreateAsync(CreateOrganizationDto input)
    {
        // ⽀付组织的费⽤[正确]
        await _paymentService.ChargeAsync(CurrentUser.Id, GetOrganizationPrice());
        
        // 通过领域服务,创建一个新的组织实例
        var organization = await _organizationManager.CreateAsync(input.Name);
        
        // 保存和更新组织到数据库中[正确]
        await _organizationManager.InsertAsync(organization);
        
        // 发送提醒邮件[正确]
        await _emailSender.SendAsync("systemadmin@issuetracking.com", "新组织", "新组织名称:"+name);
        
        //返回实例[错误]
        return organization;
    }
    private double GetOrganizationPrice()
    {
        return 42;//Gets form somewhere...
    }
}

应用服务层的输入和输出参数都是DTO,不能返回实体。至于为什么不将支付放在领域服务中,只能说业务重要也不一定放在领域服务中,详细原因说明参考[1]。

参考文献:
[1]基于ABP Framework实现领域驱动设计:https://url39.ctfile.com/f/2501739-616007877-f3e258?p=2096 (访问密码: 2096)

标签:应用逻辑,emailSender,--,private,领域,ABP,readonly,应用程序,应用层
来源: https://www.cnblogs.com/shengshengwang/p/16516035.html