David
David

Reputation: 3609

DDD - Building Repositories

If I have a Repository designed for obtaining my Aggregate Root (as defined by Eric Evans DDD) e.g. an Order Entity (the Root Aggregate) which would have OrderLine objects as children.

In some cases I just want to retrieve the top level object i.e. the Order without the OrderLines and on other occasions I would like to bring back a bit more, maybe down 2 levels etc. i.e. the Order and the associated OrderLines.

The Order / OrderLine scenario is a simple example but what if my Aggregate Root was deeper than this, possibly going down 3 or 4 levels.

What is the best / accepted way of building this into the Repository (using eager loading)??

Upvotes: 4

Views: 642

Answers (3)

Vasile Laur
Vasile Laur

Reputation: 695

Not quite sure what do you mean by Aggregate Root. As far as I know the Repository Pattern usually works with a cluster of objects that are part of your domain model, in DDD this usually refers as aggregates. How do you access you objects from a repository depends on what kind of data access layer you use in you application. I usually use NHibernate as and ORM that manages all the relationships between my classes and database tables, so when I implement a repository I can use any objects that are a part of my domain and access them as needed.

Here is an example of a repository that uses different objects:

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>;
     }
}

Upvotes: 0

Marek Tihkan
Marek Tihkan

Reputation: 1914

Udi Dahan talked about Intentional Interfaces at TechEd 2008. In his presentation he talked about how to fetch entities from repository intentionally. You can watch his presentation or slides.

The idea behind is that you fetch entities based on what to you want to accomplish. For example if you want to complete order then you create interface ICompleteOrder with Complete method and map specific FetchingStrategy to it. Then you can use something like Repository.Find<ICompleteOrder>(orderIdentity) and get this entity as you specified in FetchingStrategy.

Upvotes: 2

Aravind Yarram
Aravind Yarram

Reputation: 80194

A single model cannot be appropriate for reporting, searching, and transactional (business unit of work) behaviors. Your domain model should mainly focus on transactional behavior of a business unit of work (and also some queries...say (hypothetical e.g) Customer.allAccounts()).

I suggest you look at extended thought process on DDD called CQRS here http://gojko.net/2010/06/11/evolution-of-ddd-cqrs-and-event-sourcing/

Upvotes: 1

Related Questions