4

据我了解,限界上下文可以有模块,模块可以有许多聚合根,聚合根可以有实体。对于持久性,每个聚合根都应该有一个存储库。

由于大型项目中有众多聚合根,是否可以使用Generic Repository,一个用于准备就绪,一个用于更新?或者应该为每个聚合根有单独的存储库,这样可以提供更好的控制。

4

4 回答 4

4

GetById()在大型复杂项目中,我不建议使用通用存储库,因为除了基本的, GetAll()... 操作之外,很可能会有许多特定情况。

Greg Young 有一篇关于通用存储库的精彩文章:http: //codebetter.com/gregyoung/2009/01/16/ddd-the-generic-repository/

是否可以使用通用存储库,一个仅用于准备就绪,一个用于更新?

存储库通常不处理保存实体的更新,即它们没有Update(EntityType entity)方法。这通常由您的 ORM 的变更跟踪器/工作单元实现来处理。但是,如果您正在寻找一种将读取与写入分开的架构,那么您绝对应该看看CQRS

于 2012-12-27T12:47:36.587 回答
1

纯 DDD 是关于使隐式显式,即:不使用 List(),而是使用 ListTheCustomerThatHaveNotBeSeenForALongTime()。

这里的关键是技术实现。据我所知,领域驱动设计不提供技术选择。

通用存储库非常适合。不过,您对这个通用存储库的使用可能不符合 ddd 的精神。这取决于您的域。

于 2012-12-26T08:59:15.663 回答
1

在 Web 上发布的一些示例 DDD 应用程序中,我看到它们有一个基本存储库接口,每个聚合根存储库都从该接口继承。我,就个人而言,做事有点不同。因为存储库应该看起来像应用程序代码的集合,所以我的基本存储库接口继承自 IEnumerable 所以我有:

public interface IRepository<T> : IEnumerable<T> where T : IAggregateRoot
{

}

我确实有一些我放在那里的基本方法,但只有那些允许读取集合的方法,因为我的一些聚合根对象被封装到只能通过方法调用进行更改的地步。

要回答您的问题,是的,拥有一个通用存储库很好,但尽量不要定义任何不应被所有存储库继承的功能。而且,如果您不小心定义了某个存储库不需要的东西,请将其重构为所有确实需要它的存储库接口。

编辑:添加了如何使存储库的行为与任何其他 ICollection 对象一样的示例。

在需要 CRUD 操作的存储库上,我添加了以下内容:

    void Add(T item); //Add
    void Remove(T item); //Remove
    T this[int index] { set; } //or T this[object id] { set; } //Update
于 2012-12-26T14:52:52.773 回答
0

感谢您的评论。我采用的方法是将基本存储库接口分离为 ReadOnly 和 Updatable。每个聚合根实体都有自己的存储库,并且派生自可更新或只读存储库。聚合根级别的存储库将拥有自己的附加方法。我不打算使用通用存储库。

我选择拥有 IReadOnlyRepository 是有原因的。将来,我会将应用程序的查询部分转换为 CQRS。因此,到 ReadOnly 接口超类型的隔离将在这一点上帮助我。

于 2012-12-28T14:40:49.607 回答