DDD领域驱动设计初探(六):领域服务
前言:之前一直在搭建项目架构的代码,,有点偏离我们的主题(DDD)了,这篇我们继续来聊聊DDD里面另一个比较重要的知识点:领域服务。关于领域服务的使用,书中也介绍得比较晦涩,在此就根据博主自己的理解谈谈这个知识点的使用。
DDD领域驱动设计初探系列文章:
一、领域服务的引入在《领域驱动设计:软件核心复杂性应对之道.Eric.Eva》这本书中,作者这样定义领域服务:有些重要的领域操作,不适合归到实体(Entity)和值对象(Value Object)的类别中,这些操作从本质上讲是有些活动或动作,而不是事物,当领域中的某个重要过程或转换操作不属于实体或值对象的自然职责时,应该在模型中添加一个作为独立接口的操作,并将其申明为Service。
Service是作为接口提供的一种操作,它在模型中是独立的,与实体和值对象不同的是,它强调的是与其他对象的关系,只定义能够为客户做什么。一般情况下,对于那些放在哪个实体和值对象里面都不合适,并且它更加偏向的是实体和实体之间的关系,这种场景下,我们就需要使用领域Service。看到这里,有人就郁闷了,既然领域服务的作用是处理实体与实体之间的关系,那么为什么不把它放在应用层里面去呢,应用层的作用不就是协调任务的吗?的确,理论上来讲,放在应用层也能够解决,但博主的理解是,DDD的设计原则之一是尽量丰满领域模型,主张充血的领域模型,也就是说和领域模型相关的领域逻辑最好是方法领域层,很显然,处理实体和实体之间的关系一般来说领域逻辑,所以最好还是放在领域层。当然,这个也并不绝对,只是博主自己的理解。
我们还是来举个例子说明,比如我们权限管理里面,如果需要一个功能,将指定的用户赋予制定的权限,比如接口这样定义
void AssignPower(TB_USERS oUser, TB_ROLE oRole)
按照我们前面聚合的划分,这个接口是应该放在用户这个聚合里面还是角色聚合里面呢?很显然,感觉都不合适,这个接口包含两个聚合的实体,所以像这种情况,可以考虑用领域服务去解决。如果你非要说,方法不这样设计,放在应用层里面也是可以的。我只能说,呵呵,别闹。
二、领域服务的使用还记得我们介绍仓储的时候我们领域层里面的Services文件夹么?下面,我们就根据给指定的用户赋予制定的权限的功能一步一步写一个领域服务功能。
1、聚合划分的修改这里需要提出一个问题,对于博主在C#进阶系列——DDD领域驱动设计初探(一):聚合这篇里面聚合的划分,现在想来存在不合理的地方,上次说了应该划分为4个聚合 ,可是没有考虑到用户和角色是多对多的关系,所以需要将用户角色表TB_USERROLE单独划分为一个聚合,所以总共是5个聚合,这也就是前面说的对于DDD里面聚合的划分是比较考量程序员经验的,对于聚合划分有误造成的误解表示抱歉。我需要在相应的地方做下修改。
领域实体要继承聚合根基类:
public partial class TB_USERROLE:AggregateRoot { }
新建仓储接口和仓储实现
public interface IUserRoleRepository : IRepository<TB_USERROLE> { }
[Export(typeof(IUserRoleRepository))] public class UserRoleRepository : EFBaseRepository<TB_USERROLE>, IUserRoleRepository { }
2、领域服务代码的搭建在领域层的Services文件夹建立服务的接口和实现
public interface IPowerManagerDomainService { void AssignPower(TB_USERS oUser, TB_ROLE oRole); }
[Export(typeof(IPowerManagerDomainService))] public class PowerManagerDomainService:IPowerManagerDomainService { private IUserRepository _userRepository = null; private IRoleRepository _roleRepository = null; private IUserRoleRepository _userroleRepository = null; [ImportingConstructor] public PowerManagerDomainService(IUserRoleRepository oUserRoleRepository) { _userroleRepository = oUserRoleRepository; } public void AssignPower(TB_USERS oUser, TB_ROLE oRole) { if (oUser == null || oRole == null) { return; } var oUserRole = _userroleRepository.Find(x => x.USER_ID == oUser.USER_ID && x.ROLE_ID == oRole.ROLE_ID).FirstOrDefault(); if (oUserRole == null) { oUserRole = new TB_USERROLE(); oUserRole.ROLE_ID = oRole.ROLE_ID; oUserRole.USER_ID = oUser.USER_ID; oUserRole.ID = Guid.NewGuid().ToString(); _userroleRepository.Insert(oUserRole); } } }
温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/66921.html