Building on the infrastructure defined last time, let’s look at how we can avoid the use of magic strings when working with metadata.
When earlier discussing how to model metadata, I used
ErrorType as examples of common metadata - and posted this example that demonstrates an overhead of boilerplate.
Instead, using the techniques developed last time we can restate this more simply:
To be fair, doing this requires a couple of private members defined elsewhere - but as they’re reusable across multiple validation methods and instances, the tradeoff is pretty good:
- By making these declarations static, we avoid increasing the memory footprint of each instance and we make it easy to reuse them across the entire lifetime of the application.
- By making them private class members, instead of local variables, we gain the ability to reuse them across different validation rules.
- By making
ValidationMetadataan immutable type, we make it safe to reuse these wherever desired (if it was mutable, we’d want to create a fresh copy for each use, just to be safe).
But can we do better? These declarations still have the very magic strings we said we would like to avoid.
Yes we can - by creating a helper class that wraps each magic string with well named methods.
We define the string identifier we’ll use for storing the name of the property being validated:
Note that this is a private string - we don’t need to, or want to, expose it outside this helper class.
To create our property metadata, we create a simple a factory method, with an informative declarative name, to wrap the use of our private magic string.
To extract the value out again, an extension method that uses the same magic string to pull values out from a
ValidationResultWithMetadata in a safe way:
It’s worth pointing out that this is close to my upper limit for using expression bodied syntax; if it was any longer, I think the more traditional block syntax would be clearer.
Lastly, a predicate to make it easy to check whether a specific property name is present.
Assuming a similar support for error types, we can now redeclare our original static members using those factory methods:
Our consumers, the developers using the validation library no longer need to deal with the magic strings at all. Of course they still exist, but they’ve been hidden away where they belong, an implementation detail of the
MetadataFactory helper class.