C# 另一个应用程序架构问题
我正在尝试一些DDD,我将尝试以最简单的方式描述我所做的事情 核心项目C# 另一个应用程序架构问题,c#,domain-driven-design,n-tier-architecture,ddd-service,C#,Domain Driven Design,N Tier Architecture,Ddd Service,我正在尝试一些DDD,我将尝试以最简单的方式描述我所做的事情 核心项目 核心项目包含实体、VO和域服务。例如,我有用户实体和用户关系实体。我想我们都知道什么是用户实体。UserRelation包含有关用户如何相互连接的信息,如follow和connect(双向跟随)。正因为如此,我使用了UserDomainService和无状态方法,如Follow(user,user)和Connect(user,user) 存储库项目 我正在使用NHibernate,所以我决定不创建这样的项目。相反,我直接使用
核心项目包含实体、VO和域服务。例如,我有用户实体和用户关系实体。我想我们都知道什么是用户实体。UserRelation包含有关用户如何相互连接的信息,如follow和connect(双向跟随)。正因为如此,我使用了UserDomainService和无状态方法,如Follow(user,user)和Connect(user,user) 存储库项目 我正在使用NHibernate,所以我决定不创建这样的项目。相反,我直接使用NHibernate。例如,在我的UI中,我从数据库中获取一个用户对象,对其进行更改,然后调用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类,但现在让我们跳过它。困扰我的是这两种方法中的参数。它们接受guid,服务从数据库检索用户。另一个选项是直接传递用户对象。ChangeUsername方法类似于User entity+persistence中的方法
那么,你对此有何看法?我个人认为没有任何错误,事实上,这就是我合作的公司所做的,只要你从该服务中提取出数据访问,它就可以成为业务层的一部分,作为数据层和ui层之间的中介,它可以避免您重复自己的操作,并确保为特定操作制定的任何规则都不会触发。我的2美分 DDD适用于大型项目,对大型项目有意义。你不应该仅仅因为它很酷就把它应用到项目中。通过查看NHibernateSession,我发现您可以通过id获取用户。那么,如果NHibernateSession负责这一点,您还有哪些其他域对象?您没有存储库,为什么要强制执行DDD过热 好的,继续吧,考虑到你有一个大的域,我不清楚你为什么要创建一个新项目来承载以下功能(那里的输入guid没有问题)。IMO应用程序服务层不应该处理实体和信息产业,因为它对这个家伙来说似乎太低了。应用程序服务层负责整个应用程序,而不是某些域对象的功能。我注意到您有一个
\u userDomainService
,它似乎与您的情况更相关。如果在那里移动Follow功能没有多大意义,我会在域服务层创建另一个服务,称之为UsersManagerService
或UsersDomainService
最后,如果要实现存储库模式,请考虑通用存储库。
10X。我会试着跟着回答。我的项目很大:)。上面的代码是伪代码,不是工作代码,NHibernateSession实际上是ISession。我创建了一个新项目,因为我有一个“问题”部分。我不同意你对申请服务的看法。此外,我没有移动以下功能。核心项目对持久性一无所知,这就是为什么我们必须直接使用NHibernate或创建存储库或创建应用程序服务来包装这种持久性thing@mynkow,我不知道你有一个大项目。我想说的是应用层(取决于coz的分类)通常位于域层和基础结构层之上。对我来说,您描述的功能属于域层(域服务),它将根据需要使用基础结构层(ORM)。如果我们跳过应用层,客户端将如何使用代码执行后续操作/命令?允许使用authorizationService.IsAllowed(“操作/跟踪”,currentUser)->u1=repo.Get(user1)->u2=repo.Get(user2)->var relation=userService.follow(u1,u2)->repo.Save(relation)。这对客户来说太吵了。这就是为什么我试图将所有内容包装在一个applicationService中,它将完成上述所有工作…@mynkow是的,你是正确的,对于客户端来说,它应该非常简单-一个或两个方法调用将是理想的,这是通过包中的服务完成的。现在您需要决定将该服务放置在何处。设想2-3个其他系统想要使用Follow操作;)。对话10倍:)你能给我发一封电子邮件到gmail的mynkow问你一些简单的问题吗,10倍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);
}
}