领域启动设计DDD 应用服务与领域服务区别 电脑版发表于:2022/5/22 20:30 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); } } ``` tn2> 1.为什么不只在应用层实现这些逻辑? 你可能会说为什么不在服务层来实现领域服务里面的业务逻辑。<br> 我们可以简单的说因为这根本不是应用层的任务。因为它不是一个use-case(用例),而是一个业务操作。我们可以用同样(分配任务给用户)的逻辑在不同的用例中。 我们可能会有另外的应用场景,以某种方式更新任务并且这个更新可能包含了分配任务给另外的人。所以,我们可以在这里用相同的领域逻辑。(说白了就是业务规则重用)还有就是,我们可以有2中不同的UI(手持设备应用和Web应用)可以共享相同的领域。<br> 如果你的业务领域相对简单,那么你可以不考虑使用领域服务来实现这些逻辑。在DDD模式中这不是一个最佳实践,但ABP不会强迫你使用这种设计模式。 原文链接:https://blog.csdn.net/dongnihao/article/details/124230454