Which layer should Repositories go in?
Asked Answered
S

4

10

Which layer should the repository classes go in? Domain or Infrastructure?

Scholem answered 17/8, 2010 at 3:27 Comment(1)
DDD advocates the absence of any infrastructural concerns in domain layer. Infrastructure layer is a perfect place for the repositories. To use the repositories it is enough to reference their interfaces from the service layer.Dhaulagiri
A
2

I guess that depends how You are going to rely on them.

Question is - are You going to allow Yourself to use repositories from inside of domain?
If so - then You are forced to put them in.

I myself like to put them outside of domain. So - typical life cycle of something looks like this =>

UI => Controller => retrieve aggregate root from repo => call logic through aggregate root => if new aggregate root created, add it to repo.

Sometimes controller calls application service that does some additional stuff besides just retrieving root and calling function on it. But idea is same - domain knows nothing about persistence.


While (as I see it) there's nothing wrong with putting repos in domain (or at least abstractions of them), it makes Your domain more aware of persistence. Sometimes that can solve problems, but generally - that will definitely make Your domain more complex.

Use what seems more natural for You and be ready to switch Your ways any time.

Altigraph answered 17/8, 2010 at 8:58 Comment(3)
I would say it depends on whether we want a layered architecture or not; if we do, then there is no choice: repositories go into the domain layer.Cud
I guess that depends how You are going to rely on them. That is a wrong guess. Domain Layer should be clear of any infrastructural concerns with no alternatives according to DDD. Read my answer for more details.Tile
The "answer" by @Tile is non-sense. I explain why in my comments there, for those interested.Cud
S
24

The repository interfaces are part of the domain. The actual implementation of the interfaces should be part of the infrastructure.

Spout answered 23/8, 2010 at 7:0 Comment(8)
Well put. The interfaces are part of the domain, because it is defining the contract by which the DOs will be accessible. It is too often overlooked.Vacuum
What about the rule that defines a layered architecture (see my answer)?Cud
Excellent question. The repository interface is defined in a data definition module which is shared between the domain layer and infrastructure layer. It implies a form of relaxed layering. As stated in the book Patterns of Software Architecture, p. 39: »Argument, return, and error types of functions offered by Layer J should be built-in types of the programming language, types defined in Layer J, or types taken from a shared data definition module. Note that modules that are shared between layers relax the principles of strict layering.«Spout
The book you meant is "Pattern-Oriented Software Architecture", and the contents of page 39 can be seen here as well, in step 4. But your comment misinterprets what it says: the "data definition module" that is "shared between layers" is a Domain Entity type, not the Repository interface. In DDD, domain entities go in the Domain layer (see the DDD book). And even if we put entities into the infrastructure layer, there is nothing in the "Pattern-Oriented" book saying that a component in layer "J" can depend on a higher layer "J+1".Cud
That is completely wrong. Interfaces of repositories should not be a part of a Domain Layer. Read my answer for more details.Tile
@Tile Where did you get that "Interfaces of repositories should not be a part of a Domain Layer"? The DDD book says in page 70 about the Domain Layer: "State that reflects the business situation is controlled and used here, even though the technical details of storing it are delegated to the infrastructure". And in page 124: "Although REPOSITORIES and FACTORIES do not themselves come from the domain, they have meaningful roles in the domain design. These constructs complete the MODEL-DRIVEN DESIGN..." Both Repository interfaces and implementations belong in the Domain Model/Layer.Cud
@Rogério, you know, everyone can write whatever they want. So, I would strongly recommend you to stop reading blindly and start thinking, questioning and be skeptical about everything you read. I can help you to get a better insight on the matter if you want. For that you need to answer this question first: What is the purpose of the Domain Layer? .Tile
@Tile The purpose of the Domain Layer is to encapsulate the code that defines the domain entities within one or more bounded contexts, and that implements the associated business logic. In DDD, said code is distributed among OO classes for Entities, Value Objects, Domain Services, Factories, and Repositories. The Domain Layer uses the Infrastructure Layer below it, and is used/known by the UI and Application Layers above it.Cud
A
2

I guess that depends how You are going to rely on them.

Question is - are You going to allow Yourself to use repositories from inside of domain?
If so - then You are forced to put them in.

I myself like to put them outside of domain. So - typical life cycle of something looks like this =>

UI => Controller => retrieve aggregate root from repo => call logic through aggregate root => if new aggregate root created, add it to repo.

Sometimes controller calls application service that does some additional stuff besides just retrieving root and calling function on it. But idea is same - domain knows nothing about persistence.


While (as I see it) there's nothing wrong with putting repos in domain (or at least abstractions of them), it makes Your domain more aware of persistence. Sometimes that can solve problems, but generally - that will definitely make Your domain more complex.

Use what seems more natural for You and be ready to switch Your ways any time.

Altigraph answered 17/8, 2010 at 8:58 Comment(3)
I would say it depends on whether we want a layered architecture or not; if we do, then there is no choice: repositories go into the domain layer.Cud
I guess that depends how You are going to rely on them. That is a wrong guess. Domain Layer should be clear of any infrastructural concerns with no alternatives according to DDD. Read my answer for more details.Tile
The "answer" by @Tile is non-sense. I explain why in my comments there, for those interested.Cud
Q
2

Repository implementation classes, together with separate interfaces (if they exist) should go into the domain layer.

The reason is given by the fundamental rule to be followed in a layered architecture: a lower layer must not depend on a higher layer.

If we accept this rule (otherwise it's not a layered architecture), then putting repository implementations into the infrastructure layer would make it dependant on the domain layer, therefore violating the fundamental rule of layering.

For example, when we create a new domain entity, we put it in the domain layer; and since a repository (both its interface and its implementation) must inevitably depend on the domain entity, it means the repository must also go into the domain layer. Otherwise, we would be changing the infrastructure layer whenever a domain entity was added/removed/modified in the domain layer.

Other concerns, such as keeping the domain layer "clean" and independent of persistence details, can and should be achieved by using the appropriate infrastructure services from the implementations inside the domain layer. For example, in Java we can use JPA to implement repositories with very little code, and no SQL/JDBC or database-specific code (whether it's really a good idea to implement repositories with JPA is another discussion; in any case, JPA entities will make use of JPA annotations anyway).

References: Wikipedia, MSDN

Quixote answered 9/4, 2015 at 20:56 Comment(10)
Having the domain layer depend on the infrastructure layer makes the domain layer brittle and non-reusable across applications. Typically, one would want to be independent of the infrastructure when building a domain model, which inverts the dependency. The infrastructure must depend on the domain model and not the other way around.Karakalpak
@Karakalpak Maybe you are thinking of some architectural style other than the one from Domain Driven Design (DDD). In DDD, the domain layer contains all (or at least most) of the business logic of the application, and the whole data model (represented by the set of entity and value object types). It is not possible to reuse it in another application (unless it were only to have a different UI, which in practice never happens).Cud
Perhaps there is some misunderstanding on my part - what I am referring to are concepts from Clean Architecture (blog.cleancoder.com/uncle-bob/2012/08/13/…), which is compatible with domain-driven design. In Clean, the domain is the inner-most layer, which does not have any dependencies. It does indeed contain all of the domain logic, but no application-specific logic, and no infrastructural concerns. For better understanding, do you have an example of what you mean?Karakalpak
@Karakalpak Ah, yes, the "Clean architecture". This is incompatible with DDD (from the "Domain Driven Design" book by Eric Evans). Note that Martin's article makes no mention of DDD. Personally, I consider "Clean" a confusing and impractical architecture. DDD's conventional layered architecture, on the other hand, is simple and easy to understand, and is what developers actually employ in real projects. Clean/Onion/Hexagonal, IMO, are attempts from some authors to create something "new" they can sell, but it totally fails in practice (at least, I couldn't find a online article with a good example).Cud
I have Evans' book on my desk right now - could you point out which parts specifically make it incompatible with Clean? Reading page 70, the bottom-most paragraph, it says "Concentrate all the code related to domain model in one layer and isolate it from the UI, application and infrastructure code. ... Separating the domain layer from the infrastructure and UI layers allows a much cleaner design on each layer." The way I understand it, this means that the domain layer should not depend on any other layer, which is also the premise of Clean and co.Karakalpak
Reading into the details, I think I see what you mean - the fact that the infrastructure layer is "below" the domain layer, you imply, makes the domain layer dependent on the infrastructure layer. However, having layer independence, there should be no direct dependencies in either direction (instead, using DI, the dependencies are pushed to the composition root). However, I feel that changes to the domain should cause changes to the infrastructure. I feel that changes to the infrastructure should never cause changes to the domain. This makes the infrastructure dependent on the domain.Karakalpak
@Karakalpak Yes, in DDD the domain layer (and also the application and UI layers above it) will depend (directly and/or indirectly) on the infrastructure layer, which is independent of any other layer. The infrastructure layer should only contain application- and domain-independent infrastructure components, which can (potentially) be reused in different applications and/or domains. You see, the word "infrastructure" here only applies to general-purpose code, which by definition cannot be specific to a particular application or business domain (though it is usualy technology-specific).Cud
@Quixote how do you define the word "depend"? Do you mean that the Domain has a dependency on the infrastructure classes? Is that through an Interface? Do you maybe mean that the domain is dependent on the data which comes from infrastructure modules? I believe domain objects should not know of any specific objects which are the infrastructure objects. Usually high-abstraction components are not aware of concrete components. I.e. if I have a Product entity, it knows nothing of the outside layers, so how is it dependent on an infrastructure object - repository in this case?Enciso
@Enciso In this context, "depend" means a compile-time dependency. So, yes, components in the Domain layer will call methods on components from the Infrastructure layer below. This is what's described in the DDD book, and is what is commonly practiced in real-world projects (in my experience). In DDD, a Repository is not an infrastructure component, but a Domain component; DDD defines five such kinds of components for the Domain Model: Entity, Value Object, Factory, Domain Service, and Repository.Cud
@Rogério, quite the opposite. Books are the main source of my DDD knowledge. Saying that Domain Layer can have infrastructural concerns you show that you do not understand the intention of the Domain Layer at all. That is why I doubt your knowledge regarding DDD.Tile
T
1

Repository classes implementations should be situated in the Infrastructural Layer. Repository interfaces should be in the Service Layer.

Domain Layer should know nothing about the repositories. Strategic patterns of DDD state that Domain Layer should always be in sync with conceptual model. That means that Domain Layer should translate well known domain processes to code and vice versa. And domain process is what your domain experts should know well. And domain experts know nothing about repositories.

Another way to think about it. Let us suppose we put repositories or the interfaces of repositories into a Domain Layer. I.e. now we have the repository concept in Domain Layer code. Also, the Domain Layer should be in sync with the conceptual model of domain. So, let us ask ourselves what is the representation of repository in the conceptual model. The correct answer is that there is no repository in the conceptual model. Hence, repository can not be in Domain Layer.

All said, I still come across projects which have repositories in the Domain Layer and engineers on the projects still call it a DDD practice. I assume the problem here is that people do not pay a lot of attention to strategic patterns which lie at the heart of DDD, but just play around with the tactical patterns which may simplify coding efforts a bit.

Tile answered 20/4, 2021 at 12:42 Comment(6)
Care to show any evidence to back your claims? Where in the DDD book, for example? Or other authors/sources? Or is it all just your personal opinion?Cud
@Rogério, let us start with a simple thing which will lead to a better understanding for you. What is the purpose of the Domain Layer? Could you answer that, please?Tile
@Rogério, also answers to all your questions are in my answer. Please, take your time to read carefully before jumping to ask questions answered above.Tile
In DDD, the Domain Layer holds all source code for the Domain Model, including Entities, Value Objects, Factories, Domain Services, and Repositories. DDD defines a four layer architecture, with the topmost being the UI Layer, then Application Layer, then Domain Layer, and finally Infrastructure Layer. Compile-time dependencies are only allowed to go from higher to lower layer. You didn't respond my question at all, I asked for references, you have none. Also, I didn't say the DL can have "infrastructural concerns". Please read the last paragraph in my answer, I give a concrete example there.Cud
Oh, so you admit to have no sources/references? (What a surprise!) If you want a logical, self-contained proof that you are wrong, I give you one: A Repository interface depends on Entity types (you agree to that, right?), so it has a compile-time dependency on the Domain Layer (where all Entity types exist, right?). The Infrastructure Layer is below the Domain Layer (here we also agree, correct?). Therefore, the Repository interface cannot be defined in the Infrastructure Layer, as it would violate the fundamental rule of a Layered Architecture (ie, dependencies only go from top to bottom).Cud
@Rogério, have you ever heard about mapping? E.g. the AutoMapper. Do you know what it is used for? The Infrastructure Layer is below the Domain Layer - one more proof that you have 0 understanding of DDD. Domain Layer should depend on nothing - i.e. there is nothing below Domain Layer.Tile

© 2022 - 2024 — McMap. All rights reserved.