So what the hell is an IContextAwareService??
It is a service that knows about its context (which is the UIElement that invoked the import for the ViewModel and the services it depends on).
As I said in previous posts this is one of my favorite feature that MEFedMVVM has. Why well many times I created attached properties to extend UI functionality so that I can do proper MVVM. Yet some times it does not feel right because there is still a gap. The ViewModel does not have control over what the attached property does. Usually this is solved by exposing commands from the ViewModel and then you have another attached property that invokes the command which is magically databound ad what not. An example of something like this is VSM support I did a while ago here.
Enter MEFedMVVM with it’s IContextAwareServices.
You create this kind of service when you want to do some thing to or with the UI Element using the ViewModel as its DataContext. For example let’s say I want to know when the UIElement is Loaded and Unloaded so that my ViewModel does something smart only when you are Loading and Unloading. (please note this is just one example and I choose this example just to show the technique)
So let’s start by creating a service to do this.
First thing we have to do is create a class that Implements IContextAware. So our class will look like this
As you can see this interface has a method called InjectContext. This method will be called by MEFedMVVM with the UIElement that is requesting the ViewModel that has this service as Dependency. Since now we have the instance to the UIElement we can hook to the Loaded and Unloaded event and raise our own events that can later be mocked when unit testing the ViewModel.
So let’s create an interface to hide the default implementation of our service
and now make the service implement that interface
As you can see here all I am doing is handle the Loading and Unloading of the UIElement and raise the IContainerStatus events. In the code about I am also Exporting the service by using the ExportService attribute which tells MEFedMVVM that this is a service that can be consumed by ViewModels.
And that’s it folks. We are done. Now a ViewModel can start using this service by simple requesting it from the ExportViewModel attribute like so
One thing you should not forget is putting the [assembly: DesignTimeCatalog] somewhere in your project, otherwise MEFedMVVM will ignore your project. This is something that is not used at runtime but for design time it is crutial so that MEFedMVVM only loads your projects. MEFedMVVM will ignore any assembly at design time that does not have this attribute set!
There is a lot of potential in this approach. Currently MEFedMVVM exposes some out of the box IContextAware services which are
IViewStateManager – You can use this to invoke Visual States from your ViewModel.
IDispatcher – You can use this service to invoke delegates on the UI thread
IContainerStatus – You can use this service to get loaded and unloaded events.
and many more are coming up. But hey build your own if MEFedMVVM does not give you one already, it’s easy and yea we would love to see what you come up with, if you want to contribute we are always happy to have your code
As always feedback is most appreciated.
Go MEF it up now http://mefedmvvm.codeplex.com/