Reputation: 2574
I am working on a web application that implements DDD concepts and I know that domain service in DDD is:
Domain Services : Encapsulates business logic that doesn't naturally fit within a domain object, and are NOT typical CRUD operations - those would belong to a Repository.
But I have confusion whether a domain service is a Class,Interface or method within the domain model and how my aggregate root/domain entity will call that service?
Also Is it required to return aggregate root or domain Entity to be domain service or not?
And If my aggregate root needs to check email existence,or check password hash matching (which needs to call service/repository to hit the database).Do I need to implement that code inside a domain service or an application service?
Upvotes: 3
Views: 8355
Reputation: 4524
Talking about DDD questions is difficult because everyone needs to have common context knowledge so the explanations and business rules make sense. Therefore I use well-known concepts like payment and shopping carts.
In a DDD-centric implementation, a shopping cart is an aggregate root and each shopping item is a domain entity and the price of each item can be modeled as a value object.
Each of these objects abstracts way some business logic so they are not anemic domain models. For example
Price is a value object and it might contain methods such as conversion to different currencies, special logic for adding or deducing (considering rounding).
Similar to Price, cart-item also has some special methods like adding the count of that particular item or its color but since we can uniquely identify it in our system (shopping cart) then it is an entity.
Finally, the Shopping cart is an aggregate root. it contains shopping items and can apply business rules that may involve cart-items, for example if the total price of all times in the cart reaches a threshold a free bonus item will be added to the cart.
But these abstractions are not enough and sometimes we might have complex business rules that involve several aggregate roots, entities, ... so in this case we define Domain services.
The difference in the next abstraction is very fine. Suppose our system wants to process a request which involves interacting with the outside world (sending notifications, ...) so we abstract the outside world as interfaces and provide implementations when we need them (Ports and Adapters). Then we use these interfaces along with our aggregate roots, ... to implement our required functionality.
If during our implementation we are modeling and implementing business logics (checking invariants, ...) then we are implementing a Domain Service but if no business logic is involved and we are just coordinating some Adpaters (Ports) and Domain entities, Aggregates ... then it is an application service.
Based on these assumptions I have the following suggestions:
But I have confusion whether a domain service is a Class,Interface or method within the domain model and how my aggregate root/domain entity will call that service?
(Business/Applicaiton) Services coordinate/manage root/domain entities not vise versa.
And If my aggregate root needs to check email existence,or check password hash matching (which needs to call service/repository to hit the database).Do I need to implement that code inside a domain service or an application service?
If it is a reoccurring pattern that is also part of your business logic then it should be considered as a domain service. If is has no business logics involved then it is an application service.
Upvotes: 2
Reputation: 2954
in short: Services are always exposed as an interface, not for swappability, testability or the like, but to expose a set of cohesive operations in the form of a contract. Beyond this implication are usually assumptions of statelessness and the idea of pure fabrication according to GRASP. read more here
Upvotes: 0
Reputation: 17683
But I have confusion whether a domain service is a Class,Interface or method within the domain model
A Class
or Interface
, depending on the abstraction level. There are cases where it needs some third party stateless(!) library and the you make it as an interface with an implementation in the Infrastructure layer (in this layer you may call third party libraries).
how my aggregate root/domain entity will call that service
If it is an interface then you can pass the service to the Aggregate's method or call it outside the Aggregate and pass the output as a parameter for the Aggregate's method (the preferred way as it minimize the Aggregate's dependency).
If it is a class you can also instantiate+use it inside the Aggregate but this create a dependency from the Aggregate to the Domain service; this is not wrong in every case but you should think before using it.
Also Is it required to return aggregate root or domain Entity to be domain service or not?
No, it can return anything that resides in the Domain layer (primitive values or value objects).
And If my aggregate root needs to check email existence,or check password hash matching (which needs to call service/repository to hit the database).Do I need to implement that code inside a domain service or an application service?
If it needs to make IO calls then it is not a Domain service but an Infrastructure service or Application service.
And If my aggregate root needs to check email existence
That information must be passed as a primitive value or value object to the Aggregate after it is loaded from the persistence by the Application service.
Upvotes: 7
Reputation: 158
But I have confusion whether a domain service is a Class,Interface or method within the domain model and how my aggregate root/domain entity will call that service?
Domain service can be object that implements some interface for example IShippingCostCalculator that has concrete Implementation objects such as Company1ShippingCostCalculator and Company2ShippingCostCalculator. domain service may be called from domain model (Aggregate,Entity) or Application Service.
And If my aggregate root needs to check email existence,or check password hash matching (which needs to call service/repository to hit the database).Do I need to implement that code inside a domain service or an application service?
For External Services that requires some HTTP call or any other you have to have interface in Domain and implementation in some Infrastructure side and use DI for injecting concrete implementations. For Example IEmailSender interface in Domain Layer and EmailSender implementation out of domain layer. Application Services are only used for Domain Model Coordination (Orchestration).
Upvotes: 2