1

Over the past few months, we've been implementing an application using DDD & CQRS. One thing that I still struggle with is the best way to persist data, especially to multiple datasources of different types.

Up to this point, we've used a DAL interface layer, with multiple partial implementations of that DAL. Then in our Domain layer, we use repositories to construct/save our domain objects to n number of DALs. This works fine, until we get to some more advanced operations like pagination and searching. This has required us to not only map our data, but map our ordering/searching/pagination criteria.

I've read opinions that we should just be exposing whatever the persistence layer is (IE Entity Framework, Filesystem, web services) to the DDD layer and have the repositories access those directly, so they can take advantage of the features built into things like ORMs. This feels like a leaky abstraction to me.

Is there a pattern I'm overlooking that will help us solve these issues?

aasukisuki
  • 1,186
  • 1
  • 11
  • 33
  • 1
    Repositories should live in the DAL anyway. So they can and should know about the features you have in mind. They implement interfaces from the domain layer. These interfaces must be ignorant of those implementation details. – EagleBeak Feb 06 '15 at 13:08
  • I've always written our DDD repositories to be Domain specific, not data specific. Meaning that the repositories take and return Domain objects. If I've called a Get method on my repository, and that domain object is constructed of data from multiple sources, how would that work? Essentially right now we have 2 sets of "repositories". A repository that applies to the domain, and then DAL implementations that return DTO's specific to the data stored in that implementation. the Repository Dal then assmbles those DTO's into the domain object. – aasukisuki Feb 06 '15 at 13:25
  • 1
    I agree with repos taking and returning domain objects (aggergates, to be specific, right?). The DAL depends on the domain. So there should be no problem constructing a domain aggregate in a repository implementation in the DAL. Your problem seems to stem from your "write" repo to depending on the "read" repo - thereby being shielded from the DB-specific implementqation details you would like to use. – EagleBeak Feb 06 '15 at 13:42
  • Ok, so i think my problem might be 2 fold. 1) I need to logically separate my read and write repo definitions. At the domain level, I will rarely (if at all) need the ability to list, page or search. 2) I think more trivial for my situation, but right now my repository implementations live in my Domain layer, and the needed DALs are injected into them. Therefore my repositories depend on the DALs, not the other way around. I'm still struggling with how I would build an aggregate root domain object from multiple DALs if I were to flip the dependencies. – aasukisuki Feb 06 '15 at 14:23
  • 1
    You mean DAO instead of DAL, right? The L in DAL stands for "layer". Note that you have to able to save your aggregate in one transaction. That might or might not be tricky in your case. Shouldn't be a problem if all but one of your data sources are for reading only. Good luck! – EagleBeak Feb 06 '15 at 15:19
  • Yeah, you're right. The DAOs (implemented in various DALs) are essentially repositories that return a DTO. Then the Repository in the Domain layer takes those DTOs and assembles them into an aggregate root (and any needed value objects). Does that make sense? – aasukisuki Feb 06 '15 at 19:00

1 Answers1

3

I've read opinions that we should just be exposing whatever the persistence layer is (IE Entity Framework, Filesystem, web services) to the DDD layer and have the repositories access those directly

The Repository pattern exists to shield the domain from persistence details. You certainly do not want an extra layer of abstraction in there. Whatever persistence technology you are using, the repository can be aware of the details.

Then in our Domain layer, we use repositories to construct/save our domain objects to n number of DALs. This works fine, until we get to some more advanced operations like pagination and searching.

You said you were implementing a CQRS application. Don't you have a read model? Repositories are rehydrating entities to fulfill write business cases, not reads.

plalx
  • 42,889
  • 6
  • 74
  • 90
  • Yes, we do have read models, and that's actually an excellent point. We are going directly against the DAL's through our query layer (skipping the Domain entirely) to construct those read models. Maybe my problem is thinking that my DDD repositories even need a List / Paging / Searching functionality at all... – aasukisuki Feb 06 '15 at 13:06
  • 1
    @aasukisuki I believe it is. The repository will implement rudimentary query methods to fulfill business commands, but that's it. – plalx Feb 06 '15 at 13:50