domain driven design ports and adapters - domain-driven-design

I am new to DDD and I am trying to apply it with Hexagonal architecture.
I have the following scenario:
A user aggregate
application service
and third party REST API that I need to call before persisting the user to the repository
So I am trying to implement it using ports and adapters, so I have an interface in my application service layer that represents the third party functionality and I have the concrete implementation of that API calling exist in infrastructure layer
as the following image
As you know this interface should take some params and returns specific type, my question is where should I put the types of these params and returned type, should be exist in the infrastructure layer or inside the application service layer?
for example I have the following interface:
class GetSomeDataInput{
customerId string;
userName string;
}
class GetSomeDataResult {
userBlocked boolean;
userAvailable boolean;
}
interface IThirdPartyAPI {
getSomeInfo(GetSomeDataInput input): GetSomeDataResult;
}
As you can see the method should take specific param with specific type and return also specific type, and these classes should be implemented in both the caller side which is application service and also on the receiver side which is the concrete implementation so where should I put these types in infrastructure layer or inside the application layer or put them in a shared directory that could be accessed by both
Sorry I just wrote some pseudo code to explain my question, thank you.

These type are part of your domain, they belong to the application service. Your naming should be independent of the external API. You should name it as what it represents from the application service perspective. Hard to tell based on your code, but something like:
class CustomerIdentifiers {
customerId string;
userName string;
}
class CustomerAvailability {
userBlocked boolean;
userAvailable boolean;
}
interface ICustomerAvailabilityChecker {
getCurrentAvailability(CustomerIdentifiers id): CustomerAvailability;
}
You need to inject the concrete domain service implementation from infrastructure when you instantiate the application service class. At least as far as I understand DDD we are talking about a domain service here: https://badia-kharroubi.gitbooks.io/microservices-architecture/content/patterns/tactical-patterns/domain-application-infrastructure-services-pattern.html
Ports and adapters are good for the scenario, where you have multiple external domain services and you want to call all of them, like here: https://www.kennethlange.com/ports-and-adapters/ Sometimes they just raise events and there is no response or you get the responses on a different channel, not directly with sync behavior. Be aware that calling an external API takes time, so better to use async non-blocking solutions for it. Afaik. java or whatever your language is supports async - await, which would be probably good here, but it depends on your project.

Notice that your question applies to many different architectural styles (DDD, onion, hexagonal, clean, layered). The reason is that the question is actually a fundamental concept in OOP, which is the concept of Interface, and where languages like C# have created some confusion by introducing the keyword interface.
What I mean by that is that a C# interface is not the same as the concept of Interface in all these architectural styles, also known as Contract. As you found in your case, the C# interface defines only one part of the contract. The full contract also contains all the input and output types and optionally custom Exceptions.
Once you see this distinction, it is obvious that all the types used in the contract must be defined in the same place, as they are part of a single unit.
In ports and adapters, onion, etc. the full contract would belong to the Core. In a layered architecture, the full contract would belong to the Data Access Layer.
The advantage of Ports and adapters over layered is that all the names that appear in the contract belong to the Core/Domain, so they align with what domain experts will understand, making the contract a lot more readable. And the translation of these names to technical names which depend on the adapter technology is an internal concern of the adapter itself.

Related

DDD Domain Entities using external Services

In DDD, you're strongly encouraged to have all business logic within the domain entities instead of separate from it. Which makes sense.
You also have the idea of Domain Services to encapsulate certain pieces of logic.
What I can't work out is how to have the domain entities perform their business logic that itself depends on external services.
Take, for example, a user management system. In this there is a User domain entity, on which there are various business actions to perform. One of these is verify_email_address - which sends an email to the users email address in order to verify that it's valid.
Except that sending an email involves interactions with external services. So it seems reasonable for this logic to be encapsulated within a Domain Service that the User entity then makes use of. But how does it actually do this?
I've seen some things suggest that the User entity is constructed with references to every domain service that it needs. Which makes it quite big and bloated, and especially hard to test.
I've seen some things that suggest that you should pass in the domain service to the method that you are calling - which just feels weird. Why would someone outside of the domain entity need to pass in the EmailClient service when calling verify_email_address?
I've also then seen the suggestion that you instead pass the User entity in to the domain service, except that this seems to imply that the logic is in the domain service and not the entity.
And finally, I've seen suggestions that the entity should raise a domain event to trigger the email, which the domain service then reacts to. That means that all of the logic for whether to send the email or not - no need if it's already verified - and which email address to send it to are in the right place, and it also means that the user only needs a way to raise events and nothing more. So it feels less tightly coupled. But it also means you need a whole eventing mechanism, which is itself quite complicated.
So, am I missing something here? How can I achieve this?
(I'm working in Rust if that matters, but I don't see that it should)
What I can't work out is the best way to have the domain entities perform their business logic that itself depends on external services.
That's not your fault; the literature is a mess.
In DDD, you're strongly encouraged to have all business logic within the domain entities instead of separate from it.
That's not quite right; the common idea is that all business logic belongs within the domain layer (somewhere). But that doesn't necessarily mean that the logic must be within a domain entity.
Evans, in Chapter 5, writes:
In some cases, the clearest and most pragmatic design includes operations that do not belong to any object. Rather than force the issue, we can follow the natural contours of the problems space and include SERVICES explicitly in the model.
There are important domain operations that can't find a natural home in an ENTITY or VALUE OBJECT....
It's a very Kingdom of Nouns idea; we have code that actually does something useful, so there must be an object it can belong to.
Having a module (in the Parnas sense) in the domain layer that is responsible for the coordination of an email client and a domain entity (or for that matter, a repository) to achieve some goal is a perfectly reasonable option.
Could that module be the domain entity itself? It certainly could.
You might find, however, that coupling the management of the in-memory representation of domain information and the orchestration of a domain process that interacts with "the real world", as it were, complicates your maintenance responsibilities by introducing a heavy coupling between two distinct concepts that should instead be lightly coupled.
Clean Architecture (and the predecessors in that lineage) suggests to separate "entities" from "use cases". Ivar Jacobson's Objectory Process distinguished "entities" from "controls". So the notion of a service that is decoupled from the entity shouldn't be too alien.
Ruth Malan writes:
Design is what we do when we want to get more of what we want than we'd get by just doing it.
Finding the right design depends a lot on finding the right "what we want" for our local context (including our best guess at how this local context is going to evolve over the time window we care about).
VoiceOfUnReason has a perfectly valid answer.
I just want to boil down your question to the grits.
What I can't work out is how to have the domain entities perform their business logic that itself depends on external services.
I've also then seen the suggestion that you instead pass the User entity in to the domain service, except that this seems to imply that the logic is in the domain service and not the entity.
That's the key. All logic that belongs to domain entities should be done on domain entities. But at the same time, domain entities MUST be independent of the outside world (even other domain entities).
That's why we have domain services and application services.
Domain services are used to coordinate things between multiple entities, like transferring money between two accounts:
public class TransferService
{
IAccountRepos _repos;
public void Transfer(string fromAccountNumber, string toAccountNumber, decimal amount)
{
var account1 = _repos.Get(fromAccountNumber);
var account2 = _repos.Get(fromAccountNumber);
var money = account1.Withdraw(amount);
account2.Deposit(money);
_repos.Update(account1);
_repos.Update(account2);
}
}
That's a domain service since it's still only using the domain only.
Application services on the other hand are used to communicate over boundaries and with external services.
And it's an external service that you should create in this case. It looks similar to domain services but are at a layer over it (it can use domain services to solve its purpose).
To summarize:
Entities must be used to perform actions on themself (the easiest way is to make all setters private which forces you to add methods).
Domains services should be used as soon as two or more entities must be used to solve a problem (can even be two entities of the same type as in the example above)
Application services are used to interact with things outside the domain and can use entities and/or domain services to solve the problem.

DDD Call Adapter from Within Domain Object

I am implementing a Hexagonal Architecture with Domain Driven Design.
I have a Value object called "Address" that has a "validate()" method.
I would like to have a default validation provider for the address that is within my domain, but also allow external users to provide an overridden validator.
So I created an AddressValidationAdapter interface that can be implemented by the outside world in "dependency inversion" manner.
My question is - what is the best way to call my AddressValidationAdapter from within my Address class ?
Do I need to add it as a dependency in its constructor ?
Should I use some sort of global / static context ?
Should I use event driven approach where I post a "ValidationEvent" within my domain and subscribe to a validation success notif ?
Should I create a Service that orchestrates everything ? (Seems not very DDD like)
Thank you very much for your thoughts.
Best Regards
Alex
You mention Domain Driven Design, which is a practice that requires all business related code to go in a domain layer, and all non-busines related code to go out of that domain layer. Other than that, DDD is more concerned by how you design and evolve your business model, not so much about application architecture. The author of the DDD concept states that it can be used with any software architecture.
You also mention Hexagonal Architecture, which addresses software architecture, and has more constraints on how you structure your code. Hexagonal Architecture defines 3 concentric layers in applications:
The domain layer validates that state changing values do not violate business rules;
The ports layer is a business representation of infrastructure interactions;
The adapters layer implements the actual communication with external infrastructure.
Hexagonal Architecture also states that type references should go inwards, which means ports are not allowed to reference adapters, and the domain model is not allowed to reference other layers. A good practice is also to forbid direct reference accross different adapters. However, this is not much of a concern in your situation.
Address validation is definitely not an adapter layer concern, because it is not related to how your application interacts with an external infrastructure or data structure. This means that address validation should not be implemented as an adapter, in the sense of Hexagonal Architecture. It is not a port either for the same reasons. Address validation should go in the domain layer, because business rules validation is the purpose of the domain layer (Hexagonal Architecture) and all business related code should go in the domain layer (DDD).
However, neither DDD nor Hexagonal Architecture state anything on how you should structure your domain layer internally, so it is up to you. If you want your application to use different validation implementations, you may want to use the adapter pattern in cunjunction with a dependency injection library. Note that "adapter", here, refers to a software engineering desing pattern that has inspired the Hexagonal Architecture concept of adapter layer, but is totally independant from it.
Since the purpose of the domain layer is to validate state changing data, there should be very little code apart from validation rules implementation and data structure. If you move the latter to a validator class, there will be little left to write in the domain model objects themselves. You are probably going to end with an anemic domain model this way. You might want to consider implementing Always Valid State domain model, where validation rules are implemented directly in the domain model's setters and constructors.
If you wrote an adapter class due to the fact that you need to retrieve external data to do the actual validation, this is a good evidence that your domain model is lacking information and should be extended, rather than violating Hexagonal Architecture constraints.
Do I need to add it as a dependency in its constructor ?
Absolutely no! Value object are data and you are putting yourself in a hell with serialization/deserialization for it
Should I use some sort of global / static context ?
Not sure what you mean, but global/static context is scary, what about multiple validation done in parallel?
Should I use event driven approach where I post a "ValidationEvent" within my domain and subscribe to a validation success notif ?
Domain events are related to entities state changes, nothing is changing when you do validation
Should I create a Service that orchestrates everything ? (Seems not very DDD like)
It could be...
but also allow external users to provide an overridden validator.
I'm very curious of the details of this, why an external user would need a different validation?
Could it be that an Address has some sort of generic validation that need to be always checked, but different use cases have more stricter rules?
If that's the case why the Address itself would need to know them? It is just a value! An Integer just know that it has to be a number if in certain usage you need it to be in a range of values it's something that you add to it, but it doesn't know about it
DI/IoC approach is good and I was thinking you could do something like:
class Address {
....
validate(AddressValidationAdapter customValidation) {
// generic validation then...
customValidation.validate(whatAreYouPassingHere)
}
}
Whatever you are using as whatAreYouPassingHere, can't the code doing:
Address address = ...
address.validate(customValidator)
just read the values needed from the address and do its own validation?

DDD - Domain Service Implementation: Domain or Infrastructure

I have this classic DDD problem; I have a Domain Service "DetectPriority" that do some stuff.
PM ask me to create 2 different services; one INTERNAL ( with is FULL of business rules and involve many other Domain Models ) and another one ETERNAL ( a simple API call ).
There is a interface "DetectPriorityInterface" within the Domain.
Both Implementations MUST be active in the same time; a kind of "mixed" has to select one instead of the other in real time.
The problem is: Where do these implementations ( two implementations ) should live: in Domain Layer or Infrastructure Layer??
Internal Implementation is full of business rules and should reside in Domain Layer.
External Implementation is a simple CALL and should lives in Infrastructure.
Should we put both in Infrastructure layer?
Thanks
EDIT
Actually we have one interface "DetectPriority" and three implementations, ALL in our Domain layer ( temporary "wrong" solution ) :
InternalDetector ( with Business Rules )
ExternalDetector ( With external API call )
MixerDetector ( get both Implementations and handle the choise )
Clients use the Interface so, for Application Layer, all these stuff are trasparent; in the next, we will remove the Internal ( or External ) and Mixer and use only One Implementation. ( The idea behind all these is to understand who performs better, it is an A/BN test )
Our internal debate is: Cause InternalDetector has some domain rules that belongs ONLY to that Detector, it should live in Infrastructure layer, cause it is not an General Domain Rules. Some of us disagree with this, cause in InternalDetector we only have business rules and we don't see that in Infra Layer.
Problably the correct way should be add Internal in Domain, and External in Infra .. but it seems to be a bit confused ..
Putting all together in Infra layer would be more readable for devs...
We didn't find some stuff in books cause usually you have a single implementation of a domain service ....
The short answer is that you should implement an internal service in the domain layer and an external one in the infrastructure layer, exactly as you said in your question. This way, everything will be in its place.
An additional important thing to consider is that the code that decides which service to call should be in the domain layer too. As I can imagine from your question, you decide which detector to use using some business rule. That fact that one detector is implemented in your application, and another one is not is just an implementation detail of your system. In fact, you just decide to use one set of business rules or another one according to some condition. It is a business decision.
DDD is pretty often about difficult compromises. But when you are looking for a good compromise, I would advise never move the domain logic outside of the domain layer, and never add references from the domain layer to other ones.
This is essential.
And here is an example of how you can solve this task without violation of these rules:
// Names in this code should be changed to something with business
// meaning. For example `externalDetector` can be `governmentDetector`
// and `internalDetector` can be `corporateDetector`.
// Declare a service interface in the domain layer
public interface DetectPriority {}
// Inject both detectors in the domain service.
// Your dependency injection code should inject here
// an internal implementation and an external one,
// implemented in the infrastructure layer.
// So your DI code knows about different implementations
// but the domain service doesn't.
// For the domain service it's just two implementations
// of domain interface IDetector
IDetector _externalDetector;
IDetector _internalDetector;
// Implement the method of the domain service like this:
public Priority Detect()
{
if (weShouldUseExternalSetOfRules)
{
return _externalDetector.Detect(); // this one is implemented in your infrastructure layer
}
else
{
return _internalDetector.Detect(); // this one is implemented in your domain
}
}
In this solution you can see that:
All domain logic (an implementation of internal detector and decision which set of rules to use) is placed in the domain layer.
We don't have references to the infrastructure layer from our domain. The domain service have the reference only to IDetector interface, but this interface is declared in the domain layer.
There is not infrastructure code in the domain layer. In this case, infrastructure code means something like "call that GET method of that REST service using this set of parameters in the query string". Obviously, this code will be in the externalDetector implementation.
To be sure that it is a good way, you can take a look at this repository with a sample DDD application from famous Eric Evans' book. You can find there a service interface declared in the domain layer and the service itself implemented in the infrastructure layer. Unfortunately, there aren't examples of using this service interface inside of the domain layer in this application. But it's declared inside of the domain layer to make such a usage possible.
And you can find the same approach with a good explanation in this great article.
EDIT
According to new information in the question, if it is about A/B testing, then choosing a detector is the application-level decision. All other things remain the same. So:
MixerDetector should be in the application layer
DetectPriority interface - in the domain layer
InternalDetector in the domain layer
ExternalDetector in the infrastructure layer
And you don't need "business" names for your detectors then, because they are literally InternalDetector and ExternalDetector.
Should we put both in Infrastructure layer?
Not usually, no. Among other things, that's going to make a mess of your dependency graphs. We don't want domain code to have a dependency on infrastructure code (one of the motivations for having a domain model is so that you can implement the logic of the domain without being tightly coupled to the context that runs the domain model -- introducing infrastructure dependencies is contrary to that goal).
That doesn't necessarily mean that the infrastructure code is "far away" - see package by feature vs package by layer. They are different responsibilities (in the single responsibility principle sense), so there will usually be some separation between the two.
One aspect in which the two are very different: failure modes -- robust code that communicates across the network needs to respect the fact that the network is unreliable, but that's not a domain concern, so we don't usually want to pollute our domain code with network contingency logic.
But if you like, ignore all that -- the real heuristic is simple: we want the arrangement of code that is easiest to maintain over its entire lifetime. If in your context that means putting domain code into the infrastructure layer, then that's what you should do.
The guidelines of DDD and other styles are primarily there to help you avoid the trap of increasing the lifetime maintenance cost by deciding to do what is easy "right now".
I use to keep domain service implementations which are free of infrastructure dependencies in the domain layer. Implementations of a domain service interface which require infrastructure dependencies should reside in the infrastructure layer.
What you need to consider as well in your case is that the code which instantiates the concrete implementation of your DetectPriorityInterface at runtime has to reside in the infrastructure layer as well as it also has a direct dependency to the external domain service.
I suggest you have some factory for that job which decides on creating one or the other domain service based on some kind of parameter. But you can still use a factory interface which you can put in your domain layer. Let's call it PriorityDetectorFactoryInterface or similar. And only the concrete implementation of that factory, let's call it PriorityDetectorFactory would reside in the infrastructure layer.
If you have some application service which is responsible for handling the use case where the priority detection comes into play you would pass the PriorityDetectorFactoryInterface into this application service. At runtime the concrete implementation of the factory interface (i.e. PriorityDetectorFactory) will be injected into the application service. With that you can also keep the application layer where you usually only define the workflows for orchestrating your use cases free of infrastructure dependencies.
With that you would have:
DetectPriorityInterface in your domain layer
InternalPriorityDetector (implementing DetectPriorityInterface) in your domain layer
ExternalPriorityDetector (implementing DetectPriorityInterface) in your infrastructure layer
PriorityDetectorFactoryInterface in your domain layer as well
PriorityDetectorFactory (implementing PriorityDetectorFactoryInterface) in your infrastructure layer
...and the mentioned application service handling your use case in your application layer
Note: this is all based on the assumption that your internal domain service implementation is really free of dependencies other than stuff from the domain layer itself.

DDD Layers and External Api

Recently I've been trying to make my web application use separated layers.
If I understand the concept correctly I've managed to extract:
Domain layer
This is where my core domain entities, aggregate roots, value objects reside in. I'm forcing myself to have pure domain model, meaning i do not have any service definitions here. The only thing i define here is the repositories, which is actually hidden because axon framework implements that for me automatically.
Infrastructure layer
This is where the axon implements the repository definitions for my aggregates in the domain layer
Projection layer
This is where the event handlers are implemented to project the data for the read model using MongoDB to persist it. It does not know anything other than event model (plain data classes in kotlin)
Application layer
This is where the confusion starts.
Controller layer
This is where I'm implementing the GraphQL/REST controllers, this controller layer is using the command and query model, meaning it has knowledge about the Domain Layer commands as well as the Projection Layer query model.
As I've mentioned the confusion starts with the application layer, let me explain it a bit with simplified example.
Considering I want a domain model to implement Pokemon fighting logic. I need to use PokemonAPI that would provide me data of the Pokemon names stats etc, this would be an external API i would use to get some data.
Let's say that i would have domain implemented like this:
(Keep in mind that I've stretched this implementation so it forces some issues that i have in my own domain)
Pokemon {
id: ID
}
PokemonFight {
id: ID
pokemon_1: ID
pokemon_2: ID
handle(cmd: Create) {
publish(PokemonFightCreated)
}
handle(cmd: ProvidePokemonStats) {
//providing the stats for the pokemons
publish(PokemonStatsProvided)
}
handle(cmd: Start) {
//fights only when the both pokemon stats were provided
publish(PokemonsFought)
}
The flow of data between layers would be like this.
User -> [HTTP] -> Controller -> [CommandGateway] -> (Application | Domain) -> [EventGateway] -> (Application | Domain)
Let's assume that two of pokemons are created and the use case of pokemon fight is basically that when it gets created the stats are provided and then when the stats are provided the fight automatically starts.
This use case logic can be solved by using event processor or even saga.
However as you see in the PokemonFight aggregate, there is [ProvidePokemonStats] command, which basically provides their stats, however my domain do not know how to get such data, this data is provided with the PokemonAPI.
This confuses me a bit because the use case would need to be implemented on both layers, the application (so it provides the stats using the external api) and also in the domain? the domain use case would just use purely domain concepts. But shouldn't i have one place for the use cases?
If i think about it, the only purpose saga/event processor that lives in the application layer is to provide proper data to my domain, so it can continue with it's use cases. So when external API fails, i send command to the domain and then it can decide what to do.
For example i could just put every saga / event processor in the application, so when i decide to change some automation flow i exactly know what module i need to edit and where to find it.
The other confusion is where i have multiple domains, and i want to create use case that uses many of them and connects the data between them, it immediately rings in my brain that this should be application layer that would use domain APIs to control the use case, because I don't think that i should add dependency of different domain in the core one.
TL;DR
What layer should be responsible of implementing the automated process between aggregates (can be single but you know what i mean) if the process requires some external API data.
What layer should be responsible of implementing the automated process between aggregates that live in different domains / micro services.
Thank you in advance, and I'm also sorry if what I've wrote sounds confusing or it's too much of text, however any answers about layering the DDD applications and proper locations of the components i would highly appreciate.
I will try to put it clear. If you use CQRS:
In the Write Side (commands): The application services are the command handlers. A cmd handler accesses the domain (repositories, aggreagates, etc) in order to implement a use case.
If the use case needs to access data from another bounded context (microservice), it uses an infraestructure service (via dependency injection). You define the infraestructure service interface in the application service layer, and the implementation in the infra layer. The infra then access the remote microservice via http rest for example. Or integration through events.
In the Read Side (queries): The application service is the query method (I think you call it projection), which access the database directly. There's no domain here.
Hope it helps.
I do agree your wording might be a bit vague, but a couple of things do pop up in my mind which might steer you in the right direction.
Mind you, the wording makes it so that I am not 100% sure whether this is what you're looking for. If it isn't, please comment and correct my on the answer I'll provide, so I can update it accordingly.
Now, before your actual question, I'd firstly like to point out the following.
What I am guessing you're mixing is the notion of the Messages and your Domain Model belonging to the same layer. To me personally, the Messages (aka your Commands, Events and Queries) are your public API. They are the language your application speaks, so should be freely sharable with any component and/or service within your Bounded Context.
As such, any component in your 'application layer' contained in the same Bounded Context should be allowed to be aware of this public API. The one in charge of the API will be your Domain Model, that's true, but these concepts have to be shared to be able to communicate with one another.
That said, the component which will provide the states to your aggregate can be viewed from two directions I think.
It's a component that handles a specific 'Start Pokemon Match' Command. This component has the smarts to know to firstly retrieve the states prior to being able to dispatch a Create and ProvidePokemonStats command, thus ensuring it'll consistently create a working match with the stats in it by not dispatching any of both of the external stats-retrieval API fails.
Your angle in the question is to have an Event Handling Component that reacts on the creation of a Match. From here, I'd state a short-lived saga would be in place, as you'd need to deal with the fault scenario of not being able to retrieve the stats. A regular Event Handler is likely to lean to deal with this correctly.
Regardless of the two options you select, this service will deal with messages, a.k.a. your public API. As such it's within your application and not a component others will deal with directly, ever.
When it comes to your second question, I feel the some notion still holds. Two distinct applications/microservices only more so suggests your talking about two different Bounded Contexts. Certainly then a Saga would be in place to coordinate the operations between both contexts. Note that between Bounded Contexts, you want to share consciously when it comes to the public API, as you'd ideally not expose everything to the outside world.
Hope this helps you out and if not, like I said, please comment and provide me guidance how to answer your question properly.

In which layer should Specification Pattern objects be "new'ed up"?

So, I've looked at some posts about the Specification Pattern here, and haven't found an answer to this one yet.
My question is, in an n-layered architecture, where exactly should me Specifications get "newed" up?
I could put them in my Service Layer (aka, Application layer it's sometimes called... basically, something an .aspx code-behind would talk to), but I feel like by doing that, I'm letting business rules leak out of the Domain. If the Domain objects are accessed some other way (besides the Service Layer), the Domain objects cannot enforce their own business rules.
I could inject the Specification into my Model class via constructor injection. But again, this feels "wrong". I feel like the only thing that should be injected into Model classes are "services", like Caching, Logging, dirty-flag tracking, etc... And if you can avoid it, to use Aspects instead of littering the constructors of the Model classes with tons of service interfaces.
I could inject the Specification via method injection (sometimes referred to as "Double Dispatch"???), and explicitly have that method encapsulate the injected Specification to enforce its business rule.
Create a "Domain Services" class, which would take a Specification(s) via constructor injection, and then let the Service Layer use the Domain Service to coordinate the Domain object. This seems OK to me, as the rule enforced by the Specification is still in the "Domain", and the Domain Service class can be named very much like the Domain object it's coordinating. The thing here is I feel like I'm writing a LOT of classes and code, just to "properly" implement the Specification pattern.
Add to this, that the Specification in question requires a Repository in order to determine whether it's "satisfied" or not.
This could potentially cause performance problems, esp. if I use constructor injection b/c consuming code could call a property that perhaps wraps the Specification, and that, in turn is calling the database.
So any ideas/thoughts/links to articles?
Where is the best place to new up and use Specifications?
Short answer:
You use Specifications mainly in your Service Layer, so there.
Long answer:
First of all, there's two questions here:
Where should your specs live, and where should they be new'd up?
Just like your repository interfaces, your specs should live in the domain layer, as they are, after all, domain specific. There's a question on SO that discusses this on repository interfaces.
Where should they be new'd up though? Well, I use LinqSpecs on my repositories and mostly ever have three methods on my repository:
public interface ILinqSpecsRepository<T>
{
IEnumerable<T> FindAll(Specification<T> specification);
IEnumerable<T> FindAll<TRelated>(Specification<T> specification, Expression<Func<T, TRelated>> fetchExpression);
T FindOne(Specification<T> specification);
}
The rest of my queries are constructed in my service layer. That keeps the repositories from getting bloated with methods like GetUserByEmail, GetUserById, GetUserByStatus etc.
In my service, I new-up my specs and pass them to the FindAll or FindOne methods of my repository. For example:
public User GetUserByEmail(string email)
{
var withEmail = new UserByEmail(email); // the specification
return userRepository.FindOne(withEmail);
}
and here is the Specification:
public class UserByEmail : Specification<User>
{
private readonly string email;
public UserByEmail(string email)
{
this.email = email;
}
#region Overrides of Specification<User>
public override Expression<Func<User, bool>> IsSatisfiedBy()
{
return x => x.Email == email;
}
#endregion
}
So to answer your question, specs are new'd up in the service layer (in my book).
I feel like the only thing that should be injected into Model classes
are "services"
IMO you should not be injecting anything into domain entities.
Add to this, that the Specification in question requires a Repository
in order to determine whether it's "satisfied" or not.
That's a code smell. I would review your code there. A Specification should definitely not require a repository.
A specification is an implementation check of a business rule. It has to exist in the domain layer full stop.
Its hard to give specifics on how you do this as every codebase is different, but any business logic in my opinion needs to be in the domain layer and nowhere else. This business logic needs to be completely testable and coupled loosely from UI, database, external services and other non-domain dependencies. So I would definitely rule out 1, 2, and 3 above.
4 is an option, at least the specification will live in your domain layer. However the newing up of specifications depends really again on the implementation. We usually use depencency injection, hence the newing up of pretty much all of our objects is performed via an IOC container and corresponding bootstrapping code (i.e. we usually wire the application fluently). However we would never directly link business logic directly to e.g. UI model classes and the like. We usually have contours/boundaries between things such as UI and domain. We usually define domain service contracts, which can then be used by outside layers such as the UI etc.
Lastly, my answer is assuming that the system you are working on is at least some way complex. If it is a very simple system, domain driven design as a concept is probably too over the top. However some concepts such as testability, readibility, SoC etc should be respected regardless of the codebase in my opinion.

Resources