I have just read the following blog entry: Validation and DDD
By Vladimir Khorikov.
The blog talks about using the following patterns for validating an entity object:
- IsValid method
- Check validity in application services layer
- TryExecute pattern
- Execute/CanExecute pattern
Please see the code below:
public Person(AbstractValidator<Applicant> validator, IRulesOfferCalculator rulesOfferCalculator, int iD,
string name, DateTime dateOfBirth, string Address)
{
_iD = iD;
_name = name;
_dateOfBirth = dateOfBirth;
_Address = Address;
_validator = validator;
_rulesOfferCalculator = rulesOfferCalculator;
_validator.ValidateAndThrow(this);
}
Note that the validation is done inside the constructor here. Why is this not an option? Is this an anti pattern?
Please note that I am asking specifically in the context of a rich domain model. I am using Fluent Validation rather than attributes.
Best Answer
I see two anti-patterns here
More generally, I think there's a bit of confusion in Khorikov's essay: we don't validate entities, we validate state. The entity is just an identity progressing from one state to the next.
For more on this point, see Stuart Halloway's 2011 talk.
The state that you are validating is a value object, in Evans's language.
Throwing an ArgumentException in the constructor when the state you've been given doesn't satisfy your invariant is a perfectly reasonable thing to do.
But I still wouldn't inject a validator to do the state checking -- that sounds as though we are treating the entity as a dumb bag of state, with all of the state living elsewhere. Compare with Martin Fowler's discussion of anemic domain models, and you'll see what I mean.
I'm not a fan; but the reasoning is a bit complicated.
So the first thing to notice is that this is a query, which means it should be safe; it doesn't induce a mutation in the entity.
What distinguishes this query from being a full function is the current state of the entity. That is to say, CanDeliver is partial application, with an implicit variable bound to the current (immutable) state. So let's make that binding explicit:
Notice that the entity now goes away -- that is, the law of Demeter is telling us that
CanDeliver
belongs on the state, not on the entity.If that's the case, then you can call State.CanDeliver any time you like, in the controller, or even in the client when composing the request. But as David Arno points out, you still have the race, which is why Khorikov still needs the check.
Injecting domain behaviors into an entity is weird, and my guess probably wrong in most cases.
Review the definition of SERVICE in Domain Driven Design
In common cases, a domain service is passed to an entity as an argument, rather than embedded within the entity as though it were a piece of state.