Why is Enforce.Argument Named Like This?
Colin Jack has raised an interesting point about Enforce helper class from the Lokad Shared Libraries, that needs a post of its own to reply properly:
I'm also not finding the method names very descriptive, for example "Enforce.Argument" doesn't tell me much about what we're enforcing.
Initially the naming was similar to the naming in the Autofac's enforcement methods and it has done exactly what it says:
Enforce.ArgumentNotNull(someArgument, "someArgument");
Enforce.ArgumentNotNullOrEmpty<T>(someString, "someString");
Eventually, following processes took place in parallel:
- Number of projects benefiting from Lokad.Shared.dll expanded (and methods with 3-4 Enforce.ArgumentNotNullOrEmpty in the start didn't look nice at all).
- Efficient argument reflection was introduced.
- Strongly-typed validation Rules were implemented in the final design and started being used all across the codebase to make it more stable and checked. By the way, the initial design choice that rules never accept null objects made the implementation way more simple (that's how it always is with the good citizenship principle).
All this led to the gradual evolution of the method signatures towards representation that would be:
- more compact;
- have high performance;
- would keep same meaning if additional validation rules were added to the same enforce statements.
Here's how everything looks now:
// without rules we always enforce good citizenship
// that is implicit
Enforce.Argument(() => someArgument);
Enforce.ArgumentNotEmpty(() => someString);
// with rules we check for nulls and then run any rules
Enforce.Argument(() => someArgument, SomeCompsiteValidator);
Enforce.Argument(() => someString, StringIs.NotEmpty, StringIs.Limited(1,20));
Obviously, additional validation rules, if fired, will also use the derived name of the variable, while throwing the exception.
By the way, if a new reader starts wondering about this weird lambda syntax, I suggest to check out the post on retrieving variable or parameter name in C# for more details.
If you need to check multiple arguments without running any rules, then you can use the following form:
Enforce.Arguments(() => arg1, () => arg2, () => arg3);
I hope that this Enforce thing starts making some sense now.
Please do not hesitate to ask questions or provide additional feedback on the Shared Libraries.
Wednesday, January 14, 2009 at 1:16