Reputation: 11599
As I understand, the Bounded Context can have modules, the modules can have many aggregate roots, the aggregate root can have entities. For the persistence, each aggregate root should have a repository.
With the numerous aggregate roots in a large project, is it okay to use a Generic Repository, one for ready only and one for update? Or should have separate repository for each aggregate root which can provide better control.
Upvotes: 4
Views: 1824
Reputation: 11599
Thanks for the comments. The approach that I took was separated the base repository interface into ReadOnly and Updatable. Every aggregate root entity will have it's own repository and is derived from Updatable or readonly repository. The repository at the aggregate root level will have it's own additional methods. I'm not planning to use a generic repository.
There is a reason I choose to have IReadOnlyRepository. In the future, I will convert the query part of the app to a CQRS. So the segregation to a ReadOnly interface supertype will help me at that point.
Upvotes: 0
Reputation: 2691
On some of the sample DDD applications that are published on the web, I have seen them have a base repository interface that each aggregate root repository inherits from. I, personally, do things a bit differently. Because repositories are supposed to look like collections to the application code, my base repository interface inherits from IEnumerable so I have:
public interface IRepository<T> : IEnumerable<T> where T : IAggregateRoot
{
}
I do have some base methods I put in there, but only ones that allow reading the collection because some of my aggregate root objects are encapsulated to the point that changes can ONLY be made through method calls.
To answer your question, yes it is fine to have a generic repository, but try not to define any functionality that shouldn't be inherited by ALL repositories. And, if you do accidentally define something that one repository doesn't need, refactor it out into all of the repository interfaces that do need it.
EDIT: Added example of how to make repositories behave just like any other ICollection object.
On the repositories that require CRUD operations, I add this:
void Add(T item); //Add
void Remove(T item); //Remove
T this[int index] { set; } //or T this[object id] { set; } //Update
Upvotes: 1
Reputation: 14080
In a large complex project, I wouldn't recommend using a generic repository since there will most likely be many specific cases beyond your basic GetById()
, GetAll()
... operations.
Greg Young has a great article on generic repositories : http://codebetter.com/gregyoung/2009/01/16/ddd-the-generic-repository/
is it okay to use a Generic Repository, one for ready only and one for update?
Repositories generally don't handle saving updates to your entities, i.e. they don't have an Update(EntityType entity)
method. This is usually taken care of by your ORM's change tracker/Unit of Work implementation. However, if you're looking for an architecture that separates reads from writes, you should definitely have a look at CQRS.
Upvotes: 4
Reputation: 2293
Pure DDD is about making implicit explicit, ie : not using List(), but rather ListTheCustomerThatHaveNotBeSeenForALongTime().
What is at stake here is a technical implementation. From What I know, domain driven design does not provide technical choices.
Generic repository fits well. Your use of this generic repository might not fit the spirit of ddd though. It depends on your domain.
Upvotes: 1