我正在尝试一些DDD,我将尝试以最简单的方式描述我所做的事情。
核心项目
核心项目包含实体、值对象和领域服务。例如,我有一个用户(User)实体和一个用户关系(UserRelation)实体。我想我们都知道什么是用户(User)实体。用户关系(UserRelation)包含有关用户如何相互连接(如关注和双向关注)的信息。因此,我有一个用户领域服务(UserDomainService),其中包含无状态方法,如Follow(user,user)和Connect(user,user)。
public class User
{
public string Name { get; set; }
public string Username { get; set; }
public void ChangeUsername(stirng newUsername)
{
ApplyEvent(new UserUsernameChanged(newUsername));
}
}
public class UserRelation
{
ctor(User1, User2, isBidirectional)
public User User1 { get; set; }
public User User2 { get; set; }
public bool IsBidirectional { get; set; }
}
public class UserDomainService
{
public UserRelation Follow(User user1, User user2)
{
return new UserRelation(user1,user2,false);
}
}
代码库项目
我使用NHibernate,所以我决定不创建这样的项目。相反,我直接使用NHibernate。例如,在我的用户界面中,我从数据库中获取一个用户对象,对其进行更改,然后调用session.Save(user)。
问题
如果我想执行以下操作,我会这样做:
- 从数据库获取一些信息
- 从服务中调用Follow(user1, user2)
- 将UserRelation对象保存到数据库中 最终应用程序代码变得有点复杂。想象一下,如果我们要在2-3个地方使用此代码,并且在某些时候我们必须对其进行重构。
我的解决方案
我的解决方案是创建一个ApplicationService项目,它将完成繁琐的工作并强制消费者使用ApplicationService而不是直接使用实体和域服务。
public class UserApplicationService
{
ctor(UserDomainService userDomainService){}
User GetUser(Guid id)
{
return NhibernateSession.Get(id)
}
public void Follow(Guid user1Id, Guid user2Id)
{
var u1 = GetUser(user1Id);
var u2 = GetUser(user2Id);
var userRelation = _userDomainService.Follow(u1,u2);
NhibernateSession.Save(userRelation);
}
public void ChangeUsername(Guid user, string newUsername)
{
user.ChangeUsername(newUsername);
NhibernateSession.Save(user);
}
}
这个应用服务好还是不好?正如您所看到的,新服务也可以充当存储库,因此我们可以创建一个UserRepository类,但现在先跳过这个。让我困扰的是两种方法中的参数。它们接受Guids,并且服务从数据库检索用户。另一种选择是直接传递User对象。ChangeUsername方法与User实体+持久性中的方法类似。
那么,您对此有什么看法?