Metadata Belongs With The Class, Not With Another Class
After reading Mike Taulty’s post “Metadata Classes – A Force for Good or Evil?”, I realized that this is something that I was highly annoyed with in the past, and never got a chance to write anything about.
If you haven’t seen them yet, “metadata classes” as Mike refers to them are a way to extend the metadata of code that doesn’t belong to you. For example, in ASP.NET Dynamic Data you get a set of tool-generated types and can’t decorate them with attributes directly because these attributes will be deleted when the code is re-generated. So what do you do? You write another class, echo the properties of the original class, and decorate them with the attributes you wanted to put on the original class’ properties.
In my humble opinion, this is a coding horror. (Not in the popular blog sense, in the original Steve McConnell sense.)
It’s perfectly fine with me that the class metadata is not specified on the class itself, because it’s auto-generated (although in scenarios like these I would often copy and maintain the auto-generated code myself – I hate to see auto-generated code in my project that I don’t fully control). My problem is with the fact that you have to write another class which has only one purpose – to be a metadata container for someone else. How are developers supposed to learn object-oriented programming principles if they are forced to write a class that has absolutely no meaning in the domain model, and serves only as a container of attributes?
Don’t get me wrong – this isn’t a trivial problem to solve. Alon Fliess and I have had the pleasure of developing an AOP framework in which metadata on types could be expressed as .NET attributes or as an XML configuration file, which contains serialized attributes mapped to the type/method/property which they decorate. The mechanics of combining this metadata, propagating it across classes and interfaces and other challenges were at the core of this framework, and enabled us to build exciting features.
I’m not suggesting that you should implement a framework for combining attributes and configuration every time you need metadata in your code. Regardless, the idea of having a class which serves as a metadata container rings the coding horror bell for me. If you have other ideas how this knot can be untied, please feel free to use the comments or write another post. :-)