CQRS - erm OOP and Validations
João P. BragançaA discussion came up recently on the DDD/CQRS forums recently, that got sidetracked into ‘where do the validations go’ (along with a lot of weird nonsense about async command queues, http status code pedantry, etc, but we’ll leave that for some other time). A large minority of developers - perhaps even a majority - seem to think that validations belong somewhere in the ‘trusted’ client.
I find this conclusion strange, as none of the .net framework code we work with on a daily basis actually works this way.
Let’s take a look at a class we use every day, System.Collections.Generic.Dictionary[of TKey, TValue]
(I know this is mono, but github supports linking to a line of code so whatever):
public void Add (TKey key, TValue value)
{
if (key == null)
throw new ArgumentNullException ("key");
// get first item of linked list corresponding to given key
int hashCode = hcp.GetHashCode (key) | HASH_FLAG;
int index = (hashCode & int.MaxValue) % table.Length;
int cur = table [index] - 1;
// walk linked list until end is reached (throw an exception if a
// existing slot is found having an equivalent key)
while (cur != NO_SLOT) {
// The ordering is important for compatibility with MS and strange
// Object.Equals () implementations
if (linkSlots [cur].HashCode == hashCode && hcp.Equals (keySlots [cur], key))
throw new ArgumentException ("An element with the same key already exists in the dictionary.");
cur = linkSlots [cur].Next;
}
}
Does this code rely on a trusted client? Of course not! It blows up in your face if you try to add a null key or a duplicate key.
This is not to say that a trusted client isn’t a nice thing to have. But at the end of the day your objects can only trust one thing: themselves. QED.