views:

130

answers:

2

My domain entities are lined up like a tree:

Root
- Child 1
-- Child 1.1
-- Child 1.2
- Child 2
-- Child 2.1
-- Child 2.2

We ended up with 2 (rather strong) opinions on how a repository should be designed around these domain objects:

Opinion 1:
I need 2 repositories Child1Repository & Child2Repository which gets managed by a RootFacade/RootManager class to call the appropriate method on the repository. The 2 child repositories handle only the DAL operations while the RootFacade is the BLL. The RootFacade exposes DTO's to the application while internally all the 3 repositories use domain objects

Opinion 2:
I need 1 repository RootRepository which handles everything (BLL + DAL). The repository exposes DTO's while internally it works with the domain objects

I would like to have some perspective on these 2 points & which is really the way to go about for a repository implementation.

Thanks for all the help

+3  A: 

Classes shouldn't take on more responsibility than they need to, and it definitely sounds like the approach of a RootRepository is the wrong way to go here. It absorbs too much complexity and is responsible for too many entities. Of the two options you presented, the first is the better choice: have more repositories that are each responsible for their own corner of your domain.

However, that said, it's not clear to me why you have a RootManager at all. I would much rather have a series of DomainObjectRepositories which each managed their own business logic internally, and only exposed the relevant public operations, then defer actual database operations to a data-access object DomainObjectDao. Having an omniscient all-the-biz-logic class is a monstrous code smell, and smacks of enterprisey overkill in this particular case.

John Feminella
Sunny
Ah, I see; that wasn't clear from your original question. However, I still think my answer stands: a `Book` can't exist without a `Library` to put it in, yet there may still be operations you want to do on `Books` that have nothing to do with `Libraries` (for example, finding a book across any library in town and not just a specific library's collection).As far as calling across multiple repositories, that's okay if the two repositories already have some kind of affiliation with each other. There's nothing inherently wrong with one repository asking another one a question.
John Feminella
I like your example of library-books since it is how my entities are lined up. The key difference in my case is that all operations are on the library like: library.AddBook(), library.IssueBook() etc. The book cannot have its own operations in my caseThere are no multiple library scenarios.
Sunny
If that's truly the case, then I'd agree that your specific case doesn't require a BookRepository to expose itself. But it still looks wrong to me to have that many objects managed by one omniscient entity. I would have a tough time believing that this was the optimal way to design things (without knowing more about your specific situation, of course).
John Feminella
A: 

We work with option 1 and it fits well for us. Say child 1 is a userRepository and child 2 is a role repositorywith the facade being the security facade. The user repository would return a user domain object that was the aggregate root and the user objects contains roles. We would only really be using the role repository for GetAllRoles.

Our domain objects have a GetDTO method that returns the dtos for transport by the facade.

I hope this helps.

Burt
So, in this case, the UserRepository will handle rules like: If a user is in role "a", he cannot be assigned role "b"The RoleRepository performs only DAL operationsIs my understanding correct?
Sunny
No that is the responsibility of you domain object to handle the business logic.Look into the specification pattern for somethign like this. No repository should contain any business logic.
Burt