10

Where should Domain Service implementations reside in the DDD project structure? If we have IDomainInterface and DomainInterface implementation, should the DomainInterface implementation reside in the Infrastructure or Core/Domain part of the solution/project ?

Vlad
  • 2,475
  • 21
  • 32
Robert
  • 3,353
  • 4
  • 32
  • 50

2 Answers2

17

Domain service interfaces and their implementation may reside in the domain layer. However, if the domain service implementation depends on infrastructure concerns then by applying the Dependency Inversion Principle, the implementation would live in the infrastructure layer while depending on an interface defined in the domain.

Most domain services will not need to depend on infrastructure concerns and will be used to model use cases that cannot find a natural home within an existing aggregate, but some domain services will.

Repositories are the most common domain services that requires infrastructure knowledge and therefore you will find their implementation living in the infrastructure layer, but there are other examples.

For instance, in the IDDD's Identity & Access bounded context, the EncryptionService interface lives in the domain while the MD5EncryptionService concrete implementation lives in the infrastructure.

plalx
  • 42,889
  • 6
  • 74
  • 90
  • 8
    Domain services have nothing to do with infrastructure – Alexey Zimarev Sep 21 '16 at 13:24
  • 4
    Only the infrastructure concern, e.g. repository, would be implemented in the infrastructure layer. The domain service and its interaction with the repository would be implemented in the domain layer. [AuthorizationService](https://github.com/VaughnVernon/IDDD_Samples_NET/blob/90fcc52d9c1af29640ec2a8a3e0e7c692f3e6663/iddd_identityaccess/Domain.Model/Access/AuthorizationService.cs) from [Implementing Domain-Driven Design](https://www.amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577) is one such example. – Martin4ndersen Sep 21 '16 at 14:08
  • 1
    @AlexeyZimarev A repository IS a domain service. Most domain services will not have to depend on infrastructure details though, but some will. For instance, you may have an Encryption domain service in an Identity & Access bounded context, where the implementation live in the infrastructure because it uses some third-party encryption library. – plalx Sep 21 '16 at 14:16
  • @Martin4ndersen That is exactly what my answer states, but you seem to be missing that a repository is a domain service, just like a concrete authentication service would be if dealing with various protocols and just like an encryption service would be. Any service interface defined within the domain is a domain service. A repository is just a special kind of domain service that is common enough so that we gave it a name. – plalx Sep 21 '16 at 14:19
  • I added more precisions in my answer. From my perspective, any service that has an interface living in the domain is a domain service. Whether the implementation depends on infrastructure concerns or not is irrelevant. The service may not be part of the ubiquitous language though, but that's another story. – plalx Sep 21 '16 at 14:40
  • I see your reasoning, but as you state it is from your perspective. I follow the definitions defined in [Implementing Domain-Driven Design](https://www.amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577). – Martin4ndersen Sep 21 '16 at 15:08
  • @Martin4ndersen I answered your comment above. – plalx Sep 21 '16 at 18:00
  • Well, I see a contradiction here. We are trying to make an ubiquitous language across different context, with domain experts, at the same time struggling to follow one, not that complicated, glossary of the domain-driven design. Both blue and red books are very clear on what domain service is, what application service is and what repository is and that these are different things. Domain service encapsulates logic that does not belong inside one aggregate. It does not interact with any infrastructure. It must use the ubiquitous language, this is why it is called the *domain* service after all. – Alexey Zimarev Sep 21 '16 at 20:20
  • @AlexeyZimarev So from what you are saying, you have infrastructure service interfaces in your domain, is that correct? That is what you are saying, by calling a repository or the above `EncryptionService` an infrastructure service. What about the [CollaboratorService](https://github.com/VaughnVernon/IDDD_Samples/blob/master/iddd_collaboration/src/main/java/com/saasovation/collaboration/domain/model/collaborator/CollaboratorService.java), is that an infrastructure service as well? The whole point of this service is to respect the UL and avoid polluting it with external concepts. – plalx Sep 21 '16 at 21:59
  • It certainly is a domain service, which also acts as an anti-corruption layer, but is implemented in the infrastructure because it speaks with a remote BC. I think you are confusing contracts which lives in the domain and implementations. Contracts are domain service contracts, but implementations are infrastructure services if they live in the infrastructure. – plalx Sep 21 '16 at 22:00
  • 4
    @AlexeyZimarev When you define a service contract in your domain, do you focus on the UL or do you focus on infrastructure concerns? I certainly hope you do focus on the UL. For instance, if your business is sending notifications and it happens that notifications are sent by email (infrastructure concern) if you implement an `EmailService` I understand why you want to call it an infrastructure service, but if you did implement a `NotificationService` instead which is aligned with your UL then I do not see why you wouldn't see it as a domain service. – plalx Sep 21 '16 at 22:11
  • I am not going to convert comments to a forum. We can continue in DDD-CQRS mailing list if you are there. – Alexey Zimarev Sep 22 '16 at 07:38
  • I think I would agree that implementation CAN reside in the Infrastructure layer. My question was about implementation, not abstraction, but then again, if the DomainService depends solely of another domain services such as repositories, it's implementation can reside in the Domain layer, cause it can be implemented only by using repository interfaces and dependency injection. – Robert Sep 22 '16 at 10:27
  • @plalx I would like to know why the down-votes to your answer tho. – Robert Sep 22 '16 at 12:32
  • 5
    @Robert Well, I do not think that they are justified, but basically they do not consider that a service needing infrastructure details is a domain service and they call it an infrastructure service. Therefore, they say that repositories or a `NotificationService` or an `EncryptionService` or the `CollaboratorService` in my examples and comments are all infrastructure services. To me that makes no sense, because the interface for these services live in the domain and should be defined with the UL in mind. – plalx Sep 22 '16 at 12:48
  • I agree that these domain services may abstract away infrastructural concerns behind domain concepts, but that doesn't make them infrastructure services from the domain perspective. Otherwise, you would have infrastructure services in your domain layer, which makes no sense at all. Strictly speaking, a domain service to them is one that only contains business logic and they call everything else an infrastructure service. From that perspective, a domain service implementation can only live in the domain so my statement that they might be implemented in the infra is wrong to them. – plalx Sep 22 '16 at 12:49
  • 4
    After explaining this to you I'm even more certain that they are wrong. **What defines the kind of service is where the interface lives, not the implementation**. You wouldn't have an application service interface in the domain for instance. – plalx Sep 22 '16 at 13:00
2

An onion or hexagonal architecture says that Infrastructure layer depends on inner layers. If a contract lives in Domain layer it is because it represents some business requirement, something that represents the ubiquitous language, therefore I consider it a domain service.

If the domain service implementation requires some specific technology (for example database access, or SMTP server access or whatever), its implementation must live in the infrastructure layer. The domain simply doesn't care about implementations, if the business experts talk about something and we decide to make this "something" a contract, it must live in Domain layer. It's all about the Domain language.

Infrastructure services should not be in the Domain layer by definition. If it is something related to infrastructure, then I doubt it has anything to do with the ubiquitous language. I would expect to see infrastructure services contracts living in Application layer, because by definition an application layer is an orchestrating layer to help domain. If the implementation requires some specific technology, again, the implementation will be in the infrastructure layer.

So, to summarize and answer this question: Where to put domain service implementations? It depends:

  • If the implementation does not require anything from application or from a specific technology. Place the implementation in domain layer. (Example: an order number that is calculated)
  • If the implementation requires anything from application layer (for example it requires accessing the Aggregate repository which, in my opinion lives in Application layer), then place the implementation in the application layer.
  • If the implementation requires a specific technology (for example access to a SMTP server, or a concrete http client) then place it in a infrastructure layer.

At the end, the important is that in Domain we care about the ubiquitous language, in application we orchestrate domain and the implementations go where they make sense to be placed depending on their dependencies (domain cannot depend on anything, application can only depend on domain).

diegosasw
  • 13,734
  • 16
  • 95
  • 159