Metadata programming is very handful in many scenarios, e.g. in Aspect Oriented Programming (AOP). Typical scenarios are
- value change notifications
- security checks
Basically all scenarios where it's necessary to write boilerplate code over methods or properties. The problem is that this boilerplate code is mixed with the business logic and it decreases the readability of the code. It can be solved by applying AOP. AOP leverages can leverage the metadata defined around method and properties. Let's look how it could be applied in context of Javascrip and WinJS library.
ECMA script 5 support metadata in form of descriptors. Basically, method Object.getOwnPropertyDescriptor(object, property_name) returns the descriptor object, aka metadata of the property or method. It's very similar to System.Reflection known form .NET.
As you can see, there are 2 possible descriptor definitions:
- value descriptors
- get/set descriptors
The difference is that the first has property "value" which refers to the function (in case of method) or value (in case of property). The latter has "get" and/or "set" properties referring to the property get/set methods. The rest are same:
It would be nice to use property descriptors for AOP or other advanced scenarios, as shown in the following code:
The above code returns ECMA5 property descriptor, skipping our custom observable metadata information.
WinJS and metadata
But we can overcome this issue with WinJS. Anyway, on WWA platform, we use WinJS to define classes which under the hood calls Object.defineProperty(). We could replace-via-extend WinJS.Class.define or just define new helper method for defining the class with the possibilities to use pre/post processing.
The whole idea is that we can do any pre/post processing when defining the class via WinJS, we could hook into the process of class definition and do the custom steps. I already used it in my previous post, but lets see it on the sample example.
Let's say we want to define a class and we want to add tracing over the selected properties.
The goal is to get the tracing automatically available over firstName property.
Step #1: custom class define function
The above code defines a list of AOP filters so that we can add there our AOP filters, in this example it'll be the tracing filter. When defining the class, all AOP filters will be applied and then the final class will be defined.
Step #2: tracing filter
The code above defines the tracing filter which uses WinJS.logging capabilities. The above code is just a demo code. It's not production ready code. Generally, AOP filter is a function which gets instance members and a reference to the base class. In general, it could be used in the scenarios where AOP filter requires a specific base class. In our case we don't need it, so we return what we get passed.
The main logic is in the expandTraceProperties method. This metod filters only trace-able properties and replaces their value with custom get/set method.
Step #3: final example
Let's use it and run the example again:
The above described approach gives the developer possibility to mark-up (attribute) the properties with the metadata and let AOP filter to be applied.
What do you think about this approach? Any other ideas how to overcome that metadata constraint?