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)??
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
.
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/
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>;
}
}
精彩评论