Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 另一个应用程序架构问题_C#_Domain Driven Design_N Tier Architecture_Ddd Service - Fatal编程技术网

C# 另一个应用程序架构问题

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,所以我决定不创建这样的项目。相反,我直接使用

我正在尝试一些DDD,我将尝试以最简单的方式描述我所做的事情

核心项目
核心项目包含实体、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);
    }
}