Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.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# DDD:一个存储库可以访问另一个存储库吗?_C#_.net_Domain Driven Design - Fatal编程技术网

C# DDD:一个存储库可以访问另一个存储库吗?

C# DDD:一个存储库可以访问另一个存储库吗?,c#,.net,domain-driven-design,C#,.net,Domain Driven Design,我是DDD的新手。 我已检查了以下回复: 询问之前,但未能找到任何相关信息 在我的应用程序中,有一个对象包含另一个对象作为属性。 我有一个主对象的存储库,但是为了检索属性的值,需要访问另一个存储库 我的问题是:第一个存储库应该访问第二个存储库,还是应用程序应该调用两个存储库并合并它们 例如: 对于两类: public class Foo1 { public int Id { get; set; } // .... More data public Foo2 foo2

我是DDD的新手。 我已检查了以下回复: 询问之前,但未能找到任何相关信息

在我的应用程序中,有一个对象包含另一个对象作为属性。 我有一个主对象的存储库,但是为了检索属性的值,需要访问另一个存储库

我的问题是:第一个存储库应该访问第二个存储库,还是应用程序应该调用两个存储库并合并它们

例如:

对于两类:

public class Foo1
{
    public int Id { get; set; }

    // .... More data

    public Foo2 foo2 { get; set; }
}

public class Foo2
{
    public int Id { get; set; }

    public int Type { get; set; }
}
代码应该是这样的:

public class Foo1Repository
{
    public Foo1 Get() { 
        return new Foo1();
    }
}

public class Foo2Repository
{
    public Foo2 Get(int foo1Id)
    {
        return new Foo2();
    }
}

public class Application
{
    public void main()
    {
        Foo1 foo1 = new Foo1Repository().Get();
        foo1.foo2 = new Foo2Repository().Get(foo1.Id);
    }
}
或者更像:

public class Foo1Repository
{
    public Foo1 Get() {
        Foo2Repository foo2Repository = new Foo2Repository();
        Foo1 foo1 = new Foo1();
        foo1.foo2 = foo2Repository.Get(foo1.Id);

        return foo1;
    }
}

public class Foo2Repository
{
    public Foo2 Get(int foo1Id)
    {
        return new Foo2();
    }
}

public class Application
{
    public void main()
    {
        Foo1 foo1 = new Foo1Repository().Get();
    }
}
当然,我很想知道是否有更好的架构


谢谢

不,不应该。您没有按照预期完全实现存储库概念

存储库只是一个保存DDD对象的接口。我想不出任何无处不在的语言要求会要求一份回购协议包含另一份回购协议。换句话说,你的主题专家永远不会说用户应该保存到数据库中的平面文件中;这没有道理

您的第一个示例最接近DDD。但是请注意,存储库和工厂之间有细微的区别,严格来说,更新域对象属于工厂或属于聚合的工厂方法这通常更适合UL。
因为存储库旨在持久化域对象,所以它们往往与持久化API(如数据库API)进行大量交互。因此,如果您需要一个存储库来聚合两个数据库,例如,您需要与存储库中的两个不同API进行交互,并且您的消费者应该对这个细节一无所知。

不,不应该。您没有按照预期完全实现存储库概念

存储库只是一个保存DDD对象的接口。我想不出任何无处不在的语言要求会要求一份回购协议包含另一份回购协议。换句话说,你的主题专家永远不会说用户应该保存到数据库中的平面文件中;这没有道理

您的第一个示例最接近DDD。但是请注意,存储库和工厂之间有细微的区别,严格来说,更新域对象属于工厂或属于聚合的工厂方法这通常更适合UL。
因为存储库旨在持久化域对象,所以它们往往与持久化API(如数据库API)进行大量交互。因此,如果您需要一个存储库来聚合两个数据库,例如,您需要与存储库中的两个不同API进行交互,您的消费者应该对这个细节一无所知。

DDD建议使用一个存储库来检索和存储一个聚合根目录;聚合根是在域中具有突出作用的实体。实体的修改必须通过聚合根进行:检索聚合根及其存储库,进行必要的修改,然后将其存储回。聚合根的组成实体不能单独检索和修改,因此它们没有存储库

在您的情况下,根据上下文,Foo1似乎是聚合根。对于Foo1,只有一个存储库就足够了;Foo2的存储库是冗余的。在检索Foo1实例后,您可以而且必须通过Foo1修改Foo1的属性Foo2;不能单独检索和修改Foo2,因此不需要Foo2存储库

然而,同样取决于上下文,如果您发现Foo2本身和Foo1都是聚合根,那么它才应该拥有自己的存储库。但是,在这种情况下,Foo1不得持有对Foo2的引用,该引用是对另一个聚合根的直接引用,这是不推荐的,并在事务中修改它;相反,它必须仅通过其标识符引用Foo2,如下面的示例所示:

公开课1 { 公共int Id{get;set;} //……更多数据 public int foo2Id{get;set;}//Foo2标识符,而不是Foo2实例 } 公开课2 { 公共int Id{get;set;} 公共int类型{get;set;} } 如果修改Foo1需要对Foo2执行相同的操作,则必须通过Foo1持有的标识符检索Foo2,如下例所示。注意,为了简单起见,该示例修改了同一事务中的两个聚合根;然而,这种修改通常发生在单独的事务中,并且最终是一致的

Foo1 Foo1=foo1Repository.findByIdfoo1Id; //修改foo1状态 Foo2 Foo2=foo2Repository.findByIdfoo1.foo1Id; //修改foo2状态 //持续变化 foo1Repository.storefoo1; foo2Repository.storefoo2;
DDD建议专门使用一个存储库来检索和存储一个聚合根目录;聚合根是在域中具有突出作用的实体。修改 实体的复制必须通过聚合根进行:检索聚合根及其存储库,进行必要的修改,然后将其存储回。聚合根的组成实体不能单独检索和修改,因此它们没有存储库

在您的情况下,根据上下文,Foo1似乎是聚合根。对于Foo1,只有一个存储库就足够了;Foo2的存储库是冗余的。在检索Foo1实例后,您可以而且必须通过Foo1修改Foo1的属性Foo2;不能单独检索和修改Foo2,因此不需要Foo2存储库

然而,同样取决于上下文,如果您发现Foo2本身和Foo1都是聚合根,那么它才应该拥有自己的存储库。但是,在这种情况下,Foo1不得持有对Foo2的引用,该引用是对另一个聚合根的直接引用,这是不推荐的,并在事务中修改它;相反,它必须仅通过其标识符引用Foo2,如下面的示例所示:

公开课1 { 公共int Id{get;set;} //……更多数据 public int foo2Id{get;set;}//Foo2标识符,而不是Foo2实例 } 公开课2 { 公共int Id{get;set;} 公共int类型{get;set;} } 如果修改Foo1需要对Foo2执行相同的操作,则必须通过Foo1持有的标识符检索Foo2,如下例所示。注意,为了简单起见,该示例修改了同一事务中的两个聚合根;然而,这种修改通常发生在单独的事务中,并且最终是一致的

Foo1 Foo1=foo1Repository.findByIdfoo1Id; //修改foo1状态 Foo2 Foo2=foo2Repository.findByIdfoo1.foo1Id; //修改foo2状态 //持续变化 foo1Repository.storefoo1; foo2Repository.storefoo2;
这个问题可能更适合于并在堆栈上获得更好的响应exchange@AvrahamL我认为您不需要为Foo2指定特定的存储库。在我看来,您只需在Foo1的存储库上创建一个方法来检索此类属性,因为它是Foo1存储库的一部分domain@Padro,谢谢你的回复。问题是,可以从系统的其他部分单独调用Foo2。这意味着它是一个业务单位。此外,这种信息的和平存储在另一个提供者中,如Foo1。既然如此,你还相信它们属于同一个存储库吗?@AvrahamL根据你的描述,Foo2似乎表现出聚合根的特征,因此需要自己的存储库。但是,Foo1实体不能通过持有Foo2类型的字段直接引用Foo2。相反,Foo1必须仅为Foo2的标识符保留一个字段。我的回答中的第二个例子进一步解释了这一点。这个问题可能更适合并在堆栈上得到更好的响应exchange@AvrahamL我认为您不需要为Foo2指定特定的存储库。在我看来,您只需在Foo1的存储库上创建一个方法来检索此类属性,因为它是Foo1存储库的一部分domain@Padro,谢谢你的回复。问题是,可以从系统的其他部分单独调用Foo2。这意味着它是一个业务单位。此外,这种信息的和平存储在另一个提供者中,如Foo1。既然如此,你还相信它们属于同一个存储库吗?@AvrahamL根据你的描述,Foo2似乎表现出聚合根的特征,因此需要自己的存储库。但是,Foo1实体不能通过持有Foo2类型的字段直接引用Foo2。相反,Foo1必须仅为Foo2的标识符保留一个字段。我的回答中的第二个案例进一步解释了这一点。