我正在尝试一些DDD,我会尝试以最简单的方式描述我所做的事情。
核心项目
核心项目包含实体,VO和域服务。例如,我有用户实体和 UserRelation 实体。我想我们都知道什么是 User 实体。 UserRelation 包含有关用户如何相互连接的信息,如follow和connect(双向跟随)。因此我使用无状态方法 UserDomainService ,如Follow(用户,用户)和Connect(用户,用户)。
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。例如,在我的UI中,我从数据库中获取用户对象,更改它然后调用session.Save(用户)。
问题
如果我想按照以下方式进行操作,请执行以下操作:
我的解决方案
我的解决方案是创建一个ApplicationService项目,该项目将执行脏工作并强制使用者使用ApplicationService而不是直接使用Entitties和Domain服务
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 entity + persistence。
那你觉得这个怎么样?
答案 0 :(得分:1)
我个人认为没有任何错误,事实上这就是我与之合作的公司所做的事情,只要你从该服务中抽象出数据访问,它就可以成为业务层的一部分,作为中介之间的中介。数据层和ui层,它可以避免重复自己,并确保为某个操作概述的任何规则都会触发。
答案 1 :(得分:1)
我的2美分。
DDD适用于大型项目。您不应该仅仅因为它是酷而将它应用于项目。通过查看NHibernateSession,我看到你可以通过id获取User。好吧,如果NHibernateSession负责你有哪些其他域对象?您没有存储库,为什么要强制DDD过热?
好的,继续前进,因为你有一个大型域名,我不清楚你为什么要创建一个新项目来托管 Follow 功能(那里的输入GUID没有任何问题)。 IMO 应用程序服务层不应该处理实体和infrustrucure,因为对于这个人来说它似乎太低了。应用程序服务层负责整个应用程序,而不是某些域对象的功能。我注意到你的_userDomainService
似乎与你的情况更相关。如果移动关注功能没有多大意义,我会在域服务层创建另一项服务,称之为UsersManagerService
或UsersDomainService
最后,如果要实现存储库模式,请考虑使用通用存储库。