ABP学习笔记:领域服务 和 应用服务 区别

本文介绍了领域驱动设计(DDD)中的领域服务和应用服务的区别,强调领域服务不应被表现层直接调用,而应用服务作为两者之间的桥梁。示例展示了如何创建和实现领域服务,以及应用层如何调用领域服务。通过这种方式,实现了业务逻辑的复用和分层架构的合规性。
摘要由CSDN通过智能技术生成

1.领域服务和Application Services 是不同的,Application Services 返回的是DTO,而领域服务返回的是领域对象(实体或者值类型)。

2.领域服务可以被应用服务和其它的领域服务调用,但是不可以被表现层直接调用(表现层可以直接调用应用服务)。

第二点就是tmd为什么我 表现层 想引用 领域服务 失败的原因。DDD是有分层架构的,每一层都有流向性!!!!!!!!

重点:项目中看到  xxxxxManger.cs 结尾的 就是 领域服务的命名约定

切记三步走:

1.创建接口

public interface ITaskManager : IDomainService
{
    void AssignTaskToPerson(Task task, Person person);
}

2.实现服务

public class TaskManager : DomainService, ITaskManager
{
    public const int MaxActiveTaskCountForAPerson = 3;

    private readonly ITaskRepository _taskRepository;

    public TaskManager(ITaskRepository taskRepository)
    {
        _taskRepository = taskRepository;
    }

    public void AssignTaskToPerson(Task task, Person person)
    {
        if (task.AssignedPersonId == person.Id)
        {
            return;
        }

        if (task.State != TaskState.Active)
        {
            throw new ApplicationException("Can not assign a task to a person when task is not active!");
        }

        if (HasPersonMaximumAssignedTask(person))
        {
            throw new UserFriendlyException(L("MaxPersonTaskLimitMessage", person.Name));
        }

        task.AssignedPersonId = person.Id;
    }

    private bool HasPersonMaximumAssignedTask(Person person)
    {
        var assignedTaskCount = _taskRepository.Count(t => t.State == TaskState.Active && t.AssignedPersonId == person.Id);
        return assignedTaskCount >= MaxActiveTaskCountForAPerson;
    }
}

3. 应用层调用领域服务

下面示例为我们展示了应用层是如何调用TaskMananger

任务服务层用给定的DTO和仓储资源去检索相关的Task和Person,并且将检索到的结果传递给TaskMananger(领域服务)。

public class TaskAppService : ApplicationService, ITaskAppService
{
    private readonly IRepository<Task, long> _taskRepository;
    private readonly IRepository<Person> _personRepository;
    private readonly ITaskManager _taskManager;

    public TaskAppService(IRepository<Task, long> taskRepository, IRepository<Person> personRepository , ITaskManager taskManager)
    {
        _taskRepository = taskRepository;
        _personRepository = personRepository;
        _taskManager = taskManager;
    }

    public void AssignTaskToPerson(AssignTaskToPersonInput input)
    {
        var task = _taskRepository.Get(input.TaskId);
        var person = _personRepository.Get(input.PersonId);

        _taskManager.AssignTaskToPerson(task, person);
    }
}

1. 为什么不只在应用层实现这些逻辑?
你可能会说为什么不在服务层来实现领域服务里面的业务逻辑。

我们可以简单的说因为这根本不是应用层的任务。因为它不是一个use-case(用例),而是一个业务操作。我们可以用同样(分配任务给用户)的逻辑在不同的用例中。 我们可能会有另外的应用场景,以某种方式更新任务并且这个更新可能包含了分配任务给另外的人。所以,我们可以在这里用相同的领域逻辑。(说白了就是业务规则重用)还有就是,我们可以有2中不同的UI(手持设备应用和Web应用)可以共享相同的领域。

如果你的业务领域相对简单,那么你可以不考虑使用领域服务来实现这些逻辑。在DDD模式中这不是一个最佳实践,但ABP不会强迫你使用这种设计模式。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董厂长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值