DDD - 构建存储库

时间:2010-11-04 17:51:53

标签: domain-driven-design repository-pattern aggregate

如果我有一个专门用于获取我的聚合根的存储库(由Eric Evans DDD定义),例如订单实体(根聚合),它将OrderLine对象作为子对象。

在某些情况下,我只想检索顶级对象,即没有OrderLines的订单,在其他情况下我想带回更多,可能是2级,即订单和相关的OrderLines。 / p>

Order / OrderLine场景是一个简单的例子,但是如果我的Aggregate Root比这更深,可能会降低3或4级。

将此构建到存储库中的最佳/可接受方式是什么(使用预先加载)?

3 个答案:

答案 0 :(得分:2)

Udi Dahan在TechEd 2008上谈到了故意接口。他在演讲中谈到了如何故意从存储库中获取实体。您可以观看他的presentationslides

背后的想法是根据您想要完成的内容获取实体。例如,如果您想完成订单,则可以使用ICompleteOrder方法创建界面Complete,并将特定地图FetchingStrategy映射到该方法。然后,您可以使用Repository.Find<ICompleteOrder>(orderIdentity)之类的内容,并按照FetchingStrategy中的指定获取此实体。

答案 1 :(得分:1)

单个模型不能适用于报告,搜索和事务(业务工作单元)行为。您的域模型应该主要关注业务工作单元的事务行为(以及一些查询......比如说(假设的)Customer.allAccounts())。

我建议您在这里查看名为CQRS的DDD扩展思维过程http://gojko.net/2010/06/11/evolution-of-ddd-cqrs-and-event-sourcing/

答案 2 :(得分:0)

不太确定Aggregate Root是什么意思。据我所知,存储库模式通常适用于作为域模型一部分的对象集群,在DDD中,这通常称为aggregates。如何从存储库访问对象取决于您在应用程序中使用的数据访问层类型。我通常使用NHibernate as和ORM来管理我的类和数据库表之间的所有关系,所以当我实现一个存储库时,我可以使用属于我的域的任何对象并根据需要访问它们。

以下是使用不同对象的存储库示例:

public interface IStoryRepository : IRepository<Story>
{
   List<Image> GetStoryImage(int id);
   List<FacebookUser> GetFbUserById(string id);
}

public class StoryRepository : Repository<Story>, IStoryRepository
{
   public List<Image> GetStoryImage(int id)
   {
       var criteria = Session.CreateCriteria(typeof(Image))
       .Add(Restrictions.Eq("Id", id))
       .SetResultTransformer(new DistinctRootEntityResultTransformer());
        return criteria.List<Image>() as List<Image>;
    }

    public List<FacebookUser> GetFbUserById(string id)
    {
       var criteria = Session.CreateCriteria(typeof(FacebookUser))
       .Add(Restrictions.Eq("Id", id))
       .SetResultTransformer(new DistinctRootEntityResultTransformer());

        return criteria.List<FacebookUser>() as List<FacebookUser>;
     }
}