Not full details here, but I'm writing this post as part-memo to myself, but also in the hope that one or two of you might make a mental bookmark to keep checking back.
In the course of my most recent project, which involve classes which wrap a common data storage mechanism (a bit like DataRows) I encountered a problem which was best solved with a solution called (coining a phrase) 'self-aware' properties. Assuming all the storage access code is provided in a common base, and using attributes to define the string name of the 'column' (to continue the DataRow analogy) to which a property is mapped:
class X
{
[MappedProperty("actualvaluename")]
public string SomeValue
{
get
{
return base.GetPropertyValue("SomeValue");
}
}
}
So far so rudimentary. However, I wanted my framework to be able to support inheritance, so that a class inheriting from another one not only could inherit it's properties, but also so it could actually override the mappings for a property defined by a base, just by using the same attribute.
Also, what I didn't want to have to do was:
a) Store mapping information in every instance of such a class (to weighty)
b) Write some behemoth registry which keeps track of all the mappings (initialisation problems, potential threading issues, not to mention a nightmare to extend and maintain)
The solution that I have produced takes a few ideas from the ideas laid out by C++ Template Meta-Programming (read this book if you want to know more: http://www.amazon.co.uk/Template-Metaprogramming-Concepts-Techniques-Beyond/dp/0321227255), but of course it all happens at run time - because Templates in C++ are not the same as C# Generics. It takes advantage of an immensely powerful feature of Extension Methods - generic extension methods (think public static void Foo<T>(this T instance, ...) ), as well dynamic Generic class instantiation using reflection to achieve the generic recursion required to build the data for each level in the class hierarchy.
All it took was a common base (with practically no methods), a static generic class plus some extension methods - and the C# type engine does the rest for you.
In a future post I will lay out the design, but for now I've run out of time (it's Fathers' day - which as many fathers will know doesn't necessarily mean that Father gets to choose what he does!)
Comments
Post a Comment