Some confusion with dependencies between Application and Infrastructure layers - domain-driven-design

When the application is using a Repository ( which is an Infrastructure service ), then Repository interface is defined within a Domain layer, while its implementation is defined within an Infrastructure layer, since that way Domain model has no outgoing dependencies.
a) If we're 100 % certain that a particular ( non-Repository ) Infrastructure service InfServ won't ever be called by any code within Domain layer, then I assume InfServ's interface doesn't need to be defined within a Domain layer?
Assuming InfServ won't be called by code within Domain layer ( and as such we don't need to define its interface within Domain layer ):
a) if InfServ will be called by Application layer's Services, I assume Application layer should have an implicit dependency on Infrastructure layer and not the other way around? In other words, both InfServ's interface and its implementation should be defined within an Infrastructure layer?
b) And the reason why it is better for Application layer to have a dependency on Infrastructure layer and not another way around is that Infrastructure layer can be reused by many applications, while Application layer is in most cases specific only to a single application and usually can't be reused by other applications?
c) If we are 100 % certain that no code within Domain layer will ever use a Repository, then we wouldn't need to define its interface within Domain layer?
UPDATE:
1)
Yes, however, the definition of domain layer can include application
services which act as a facade over the domain. The application
service usually references a repository and other infrastructural
services. It orchestrates domain objects and said services to implement
use cases.
a)
... which act as a facade over the domain
Couldn't we argue that "regular" ( those I was referring to in my question ) Application Services also act as a facade over the domain?
b)
The application service usually references a repository and other
infrastructural services.
From your reply, it seems as if you're suggesting ( though you're probably not ) that "regular" Application services don't normally reference Infrastructural services, which in fact they do ( as far as I know )?!
2)
a)
I usually merge application services, as described above, into the
domain layer.
"Regular" Application layer is also part of a BLL layer, so couldn't we argue that it is merged with Domain layer ( it actually sits on top of Domain layer )?!
b)
I tend to adhere to the Hexagonal architecture style ...
It appears Hexagonal architecture doesn't have the explicit concept of Application layer ( ie of Application Services )?
c)
Part of the benefit of declaring a repository interface in the domain
layer is that it specifies the data access requirements of the domain.
So we should include the Repository interface in Domain layer even if we domain code won't use it?
SECOND UPDATE:
2a)
If what you call a "regular" application service interacts with the
domain, I think it is acceptable to make it part of the domain
"layer". However, the domain should not directly depend on the
surrounding application service and so it is possible to split them up
into separate modules if desired.
I'm not sure whether or not you're implying that the design of Application layer ( in traditionally layered architecture ) is any different from when you merge Application layer with Domain layer using, for example, Onion architecture?
I'd say at least as far as modules are concerned, the two shouldn't be different, since in both cases we can separate Application and Domain layer modules? ( though I must confess I skipped the chaperon modules ( Evan's book ) since I didn't think I'd need that knowledge so early into learning DDD :O )
2b)
Yes because it can be contrasted with a layered architecture. A strict
layered architecture does not gel with the idea of declaring
repository interfaces in domain layer and implementing in
infrastructure layer. This is because, on the one hand, you have a
dependency in one direction, but in terms of deployment the dependency
is in the other. Hexagonal addresses these concerns by placing the
domain at the center. Take a look at the onion architecture - it is
essentially hexagonal but may be easier to grasp.
I don't yet know the MVC pattern or Asp.Net MVC, but regardless, from reading the first three parts of the series ( which confused me to the point I stopped reading it ), it appears :
a) From Onion article:
Each layer is coupled to the layers below it, and each layer is often
coupled to various infrastructure concerns.
The author is implying that in traditionally layered architecture TLA a Domain layer is coupled to Infrastructure layers, which certainly isn't true, since we normally define Infrastructure interfaces ( such as Repository interface ) within Domain layer?!
b) And if when using TLA we decide to define Infrastructure interfaces in Application layer, then Application layer also isn't coupled to Infrastructure layer?!
c) Isn't with Onion architecture an * Infrastructure layer* coupled to Application Core ( which includes Application layer ), since Infrastructure interfaces are defined in Application Core?
d) If yes to c), isn't it better to couple Application layer to Infrastructure layer ( for reasons I gave in my original question ( here I'm assuming Domain layer won't be calling Infrastructure services) )?
4)
From Onion article:
The first layer around the Domain Model is typically where we would
find interfaces that provide object saving and retrieving behavior,
called repository interfaces.
From Onion article:
The controller only depends on interfaces, which are defined in the
application core. Remember that all dependencies are toward the
center.
It appears the author is implying that since dependencies are only inwards and since Infrastructure interfaces are defined around Domain Model, that code within Domain Model shouldn't reference these interfaces. In other words, we shouldn't pass Repository reference as an argument to a method of a Domain entity ( which as you yourself has said is allowed ):
class Foo
{
...
public int DoSomething(IRepository repo)
{
...
var info = repo.Get...;
...
}
}
For reasons stated above I must confess that I fail to see the benefits of using Onion architecture or even how it is different from TLA ( assuming all Infrastructure interfaces are defined within Domain layer ) --> in other words, couldn't we depict TLA using Onion architecture diagram?!
FINAL UPDATE:
2)
b)
Yes. In TLA the domain layer would communicate directly with
infrastructure in terms of classes declared by infrastructure layer
not the other way around.
Just to be sure – you're saying that with TLA an Infrastructure interfaces would be defined in Infrastructure layer ( I know that with Hexagonal/Onion architecture they are defined in Application core )?
d)
The coupling goes both ways. The application core depends on
implementations in infrastructure and infrastructure depend on
interfaces declared in application core.
My point is that since with Onion architecture an InfServ interface is declared within Application layer ( here the assumption is that InfServ is never called by Domain Layer and as such we decide not to define InfServ interface within Domain Layer – see original 1a question ), it means that Application layer controls the InfServ interface. But I'd argue that it would be better if Infrastructure layer controlled the InfServ interface, due to reasons stated in the original 2b question?!
4)
It appears the author is implying that since dependencies are only inwards
and since Infrastructure interfaces are defined around Domain Model,
that code within Domain Model shouldn't reference these interfaces.
In my opinion, your code sample is appropriate to code.
So I was correct in saying that Onion Architecture doesn't "allow" Domain Model to reference Infrastructure interfaces, since they are defined in layer InDe ( InDe of course also resides within application core ) surrounding DM strong textand referencing them from DM would mean that dependencies go upwards from DM to InDe?
DDD is typically presented in a hexagonal/onion architectural style
which is why there may be some confusion. I think what you've probably
been doing is already hexagonal which is why it seems like it is the
same thing.
Yeah, I got that impression also. Though I do plan to look a bit deeper into the Hexagonal architecture ( especially since the new DDD book will base some examples on it ) after I finish reading Evan's book.
FOURTH UPDATE:
2)
d)
If infrastructure owned interface and implementation then the domain
or application layer would be responsible for implementing persistence
for itself.
I assume Application or Domain layers would need to implement it for themselves because referencing interfaces defined in Infrastructure layer would Onion's rule of inner layers not having dependencies on outer layers ( Infrastructure layer being the outer layer )?
4)
Domain model can reference infrastructure interfaces, such as a
repository, because they are declared together. If application layer
is split from the domain, as it is in the Onion diagram, then the domain layer
can avoid referencing interfaces because they can be defined in the
application layer.
But according to that article, Infrastructure interfaces are declared in a layer surrounding Domain Layer, which would mean it is closer to the outer edges of application core than Domain Layer – and as the article pointed out, the inner layer shouldn't have dependencies on outer layers>!
thank you

1a) Yes, however the definition of domain layer can include application services which act as a facade over the domain. The application service usually references a repository and other infrastructural services. It orchestrates domain object and said services to implement use cases.
2a,b)
I usually merge application services, as described above, into the domain layer. I tend to adhere to the Hexagonal architecture style, also called ports and adapters. The domain is at the center and is encapsulated by the application service and all external connections, including repositories, UI, and services act as ports.
2c) Part of the benefit of declaring a repository interface in the domain layer is that it specifies the data access requirements of the domain.
UPDATED
1a) I didn't intend for the application services that I mention to be distinguished from "regular" application services. If it is a facade over the domain then the rules apply.
1b) There may be services that can still be called application services, but aren't directly related to the domain and I wanted to exclude those.
2a) If what you call a "regular" application service interacts with the domain, I think it is acceptable to make it part of the domain "layer". However, the domain should not directly depend on the surrounding application service and so it is possible to split them up into separate modules if desired.
2b) Yes because it can be contrasted with a layered architecture. A strict layered architecture does not gel with the idea of declaring repository interfaces in domain layer and implementing in infrastructure layer. This is because on the one hand you have a dependency in one direction, but in terms of deployment the dependency is in the other. Hexagonal addresses these concerns by placing the domain at the center. Take a look at the onion architecture - it is essentially hexagonal but may be easier to grasp.
2c) Yes, but usually the repository interface would be referenced by an application service.
UPDATE 2
2a) They could be implemented differently, but the general responsibilities are the same. The main difference is in the dependency graph. While you can separate application services into their own modules with either architecture, the onion/hexagonal architecture emphasizes the use of interfaces to declare dependencies on infrastructure.
2ba) Yes and this is in fact a characteristic of the onion architecture.
b) Yes. In TLA the domain layer would communicate directly with infrastructure in terms of classes declared by infrastructure layer not the other way around.
c) Yes, infrastructure implements interfaces declared by domain layer.
d) The coupling goes both ways. The application core depends on implementations in infrastructure and infrastructure depends on interfaces declared in application core.
4) In my opinion, your code sample is appropriate code. There are cases where an entity needs access to a repository to perform some action. However, to improve the coupling characteristics of this code, it would be better to either define a specific interface that declares the functionality required by the entity, or if lambdas are available even better. The repository could then implement that interface and the application service would pass the repository to the entity when invoking the given behavior. This way, the entity does not depend on a general repository interface, instead it depends on a very specific role.
DDD is typically presented in a hexagonal/onion architectural style which is why there may be some confusion. I think what you've probably been doing is already hexagonal which is why it seems like it is the same thing.
UPDATE 3
2b) In TLA there would be no interfaces, or not the same kind. The domain would communicate directly with infrastructure, such as a persistence framework and so it would be responsible for persistence.
2d) If infrastructure owned interface and implementation then the domain or application layer would be responsible for implementing persistence for it self. In hexagonal/onion, the implementation of persistence is part of infrastructure - it "adapts" the abstract domain to database.
4) Domain model can reference infrastructure interfaces, such as a repository, because they are declared together. If application layer is split from domain, as it is in Onion diagram, then the domain layer can avoid referencing interfaces because they can be defined in the application layer.
UPDATE 4
2d) No that statement applies to a layered architecture with hierarchy like: UI -> Business Logic -> Data Access. The business logic layer depends on the data access layer and has to implement its data access based on the object model of the data access framework. The data access framework itself doesn't know anything about business layer.
4) The article specifies only one possible architecture. There are acceptable variations.

The only benefit I see in placing repository interfaces in the Application layer instead of the Domain is if you want to reuse the Domain DLL in another application where you would completely redefine the way you query your collections of domain entities - in other words, need completely different repositories.
However there are 2 major obstacles to that approach :
Domain layer Services. They represent processes that are at the crossroads of many entities, and thus need multiple references to do their job. It's a common and convenient thing for them to get these references by asking Repositories.
You can find an example of this in the RoutingService here.
Also, there are special cases when some entities could need the help of a repository to find a particular other entity. For instance, if you have a hierarchy of aggregate roots with parent/child relationships between them, one particular instance could say "I need the list of all my ancestors/descendants that satisfy these criteria". A repository seems like the best fit for that kind of query.

Related

DDD: Should repository reside in Domain Layer or Application Layer

In a Layered Architecture with Dependency Inversion Principle we have some Application Services (in Application Layer) and some Domain Services (in Domain Layer).
Now I want to do some validations on Object Compositions. In the red book, on chapter 5 under Validating Object Compositions somewhere it says:
But it may be best to manage that kind of validation using a Domain Service. The Domain Service can use Repositories to read the Aggregate instances it needs to validate.
Doesn't this means that repository interfaces live in domain layer?
If yes, are there any un-told truth about these repository interfaces? (maybe they can only fetch aggregates by id?)
I know that this question has been asked so many times. But I find most of the answers neglecting the blue and the red book this stackexchange thread for example
Doesn't this means that repository interfaces live in domain layer?
Yes, repository interfaces live in the domain layer for sure and usually domain services and application services (a layer above) are their consumers.
If yes, are there any un-told truth about these repository interfaces? (maybe they can only fetch aggregates by id?)
Repositories are intended to fetch and modify aggregate roots, be it for validation or any other purpose. The fetch doesn't necessarily have to happen with id, it may happen with other parameters as situation demands.

DDD why should domain model define interfaces for infrastructure

While studying DDD I'm wondering why the Domain model need to define interfaces for the Infrastructure layer.
From my reads I got that a high level (domain model, application service, domain service) defines interfaces that need to be implemented by a lower layer (infrastructure). Simple.
From this idea I think it makes sense that an application level (in a high level) defines interfaces for a lower one (infrastructure) because the application level will use infrastructure components (A repository is a usual client of the applicaiton layer) but doesn't want to be tied to any special implementation.
However, this is confusing when I see in some books a domain level defining infrastructure interfaces because a domain model will not use ever a repository because we want our domain model "pure".
Am I missing something?
While studying DDD I'm wondering why the Domain model need to define interfaces for the Infrastructure layer.
It doesn't really -- that's part of the point.
The domain model defines the interfaces / contracts that it needs to do work, with the promise of happily working with any implementation that conforms to the contract.
So you can choose to implement the interface in your application component, or in the infrastructure component, or where ever makes sense.
Note the shift in language from "layer" to "component". Layers may be too simplistic to work -- see Udi Dahan 2007.
I came across the same question myself. From my understanding, the reason behind this is that you want the application to only consume objects/interfaces defined in the Domain Model. It also helps to keep one repository per aggregate since they sit next to each other in the same layer.
The fact that the Application layer has a reference to the Infrastructure layer is only for the purpose of dependency injection. Your Application layer services should call these interfaces exposed in the Domain layer, get Domain Objects (POCOs), do things and possibly call interfaces again; for example to commit a transaction. This is why for example the Unit of Work pattern exposes its action through a Domain Layer interface.

Implementation differences between Translation and AntiCorruption layers

Conceptually, I understand the difference between Translation and AntiCorruption layers, but as far as implementation is concerned, is the difference between the two that with Translation layer we don't have a Facade, nor Service(s) residing within Translation layer nor do we have an Adapter, but instead domain code itself ( residing within Bounded Context ) calls a Translator?
a. If external system ES is actually part of another application and offers functionality ( which our Bounded Context BC needs ) via its Application layer and directly from its Domain layer, how should our BC request the services it needs? By communicating with ES's Application layer or by communicating ( via Translation/AntiCorruption layer ) with ES's Domain layer?
b. Why isn't Translation/AntiCorruption layer also needed when our BC requests functionality via ES's Application layer, since the data it receives via ES's Application layer still needs to be translated into domain concepts?
c. If ES is actually part of our own application, then I assume only option is for our BC to request the functionality by communicating "directly" with ES's domain layer via Translation/AntiCorruption layer?
Translation is what the ACL does. These aren't separate concepts. Implementation can be done in various ways. The point though is to protect your domain from external systems. The ACL does this by translating the external system's model to your local domain model.
2a. The local BC should communicate with an external BC either through the application service or through an open-host service, which is basically a web service. The former approach is only feasible if you the two BCs are developed in tandem and you have direct libraries that implement both. The latter applies to 3rd party BCs or BCs that are fully encapsulated by the service.
2b. This does still need to happen, unless the two BCs are developed in tandem and have a shared kernel. I'm not a huge fan of shared kernel however.
2c. Your BC still needs to communicate with ES via ES's application service. It should never go directly to domain objects. Better yet, have the ES functionality exposed by web service which BC would call.

DDD and implementing persistence

I am getting my feet wet with DDD (in .Net) for the first time, as I am re-architecting some core components of a legacy enterprise application.
Something I want to clear up is, how do we implement persistence in a proper DDD architecture?
I realize that the domains themselves are persistence ignorant, and should be designed using the "ubiquitous language" and certainly not forced into the constraints of the DAC of the month or even the physical database.
Am I correct that the Repository Interfaces live within the Domain assembly, but the Respository Implementations exist within the persistence layer? The persistence layer contains a reference to the Domain layer, never vice versa?
Where are my actual repository methods (CRUD) being called from?
Am I correct that the Repository Interfaces live within the Domain
assembly, but the Repository Implementations exist within the
persistence layer? The persistence layer contains a reference to the
Domain layer, never vice versa?
Yes, this is a very good approach.
Where are my actual repository methods (CRUD) being called from?
It might be a good idea to not think in CRUD terms because it is too data-centric and may lead you into Generic Repository Trap. Repository helps to manage middle and the end of life for domain objects. Factories are often responsible for beginning. Keep in mind that when the object is restored from the database it is in its midlife stage from DDD perspective. This is how the code can look like:
// beginning
Customer preferredCustomer = CustomerFactory.CreatePreferred();
customersRepository.Add(preferredCustomer);
// middle life
IList<Customer> valuedCustomers = customersRepository.FindPrefered();
// end life
customersRepository.Archive(customer);
You can call this code directly from you application. It maybe worth downloading and looking at Evan's DDD Sample. Unit of Work pattern is usually employed to deal with transactions and abstracting your ORM of choice.
Check out what Steve Bohlen has to say on the subject. The code for the presentation can be found here.
I was at the presentation and found the information on how to model repositories good.
Am I correct that the Repository Interfaces live within the Domain
assembly, but the Repository Implementations exist within the
persistence layer? The persistence layer contains a reference to the
Domain layer, never vice versa?
I disagree here, let's say a system is comprised of the following layers:
Presentation Layer (win forms, web forms, asp.net MVC, WPF, php, qt, java, , ios, android, etc.)
Business Layer (sometimes called managers or services, logic goes here)
Resource Access Layer (manually or ORM)
Resource/Storage (RDBMS, NoSQL, etc.)
The assumption here is that the higher you are the more volatile the layer is (highest being presentation and lowest being resource/storage). It is because of this that you don't want the resource access layer referencing the business layer, it is the other way around! The business layer references the resource access layer, you call DOWN not UP!
You put the interfaces/contracts in their own assembly instead, they have no purpose in the business layer at all.

Which layer should Repositories go in?

Which layer should the repository classes go in? Domain or Infrastructure?
The repository interfaces are part of the domain. The actual implementation of the interfaces should be part of the infrastructure.
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
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.
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.

Resources