This one is just awesome, and is actually a feature that can be found in most DI frameworks. MVVM Light uses SimpleIoc to register viewmodels and service classes at application launch (or during the app lifetime). Constructor injection means that you can specify a parameter in a class his constructor. When that class gets instantiated SimpleIoc will try to find a registered class of the same type as the parameter, when it finds one, that instance will get injected as the parameter of the constructor. Here’s an example, let’s say that in the ViewModelLocator, we register a navigation service.
We state here that we want to register an INavigationService in the IOC container, when it creates the instance we want it to be of type NavigationService. This “record” in the IOC container doesn’t have an instance yet, it gets instantiated when we fetch it from the container the first time. There are some occasions where you would want to create an instance of a class immediately when it gets registered. the Register<T> function of SimpleIoc has an overload to do just that.
Just pass in true as a parameter and it will create an instance right there and then.
Now we want to use the NavigationService in the MainViewModel.
SimpleIoc will search for a registered class of type INavigationService and will inject it in this constructor. This saves us the hassle of manually contacting the IOC container and requesting the correct instance.
WARNING: do be careful with this, the order in which you register your classes with the IOC container can be important, especially when using the overload to create instances. If I would create the MainViewModel before the NavigationService is registered I would get a nullreference exception. So be aware of that.
The SimpleIoc library works great and is a cool, lightweight addition to MVVM Light, but it is actually really lightweight. It is a very realistic scenario that for larger apps the SimpleIoc just won’t do (or you’re like me and want to try out how hard it is to replace it with another one). In this example I’m going to replace SimpleIoc with AutoFac, another well known and very powerful IOC service.
First of all, we’re going to need the AutoFac libraries and the extra library that allows us to use the ServiceLocator, just like SimpleIoc does. So either from the package manager console or from the UI, add the CommonServiceLocator extra for AutoFac, the AutoFac libraries are a dependency so they’ll get installed as well. I’m using a brand new Windows Phone 8 project for this, started from the MVVM Light project template.
The only place we’ll need to change some code is in the ViewModelLocator.
This is the new ViewModelLocator constructor, I’ve put the old SimpleIoc code in comments so it’s easy to compare
And that’s it, we declare a ContainerBuilder, set it as the LocatorProvider. The container is then used to register everything we need. The SimpleIoc overload that creates an instance upon registering would look something like this in AutoFac.
That’s it, constructor injection should still work exactly like before with SimpleIoc.
MVVM Light has something called the messenger, it registers classes as listeners and can send messages to them. This is commonly used to do communication between viewmodels. Generally I would create a message class for each type of message that I want to send, but MVVM Light has some build in messages that we can use.
GenericMessage<T>(T content) A message that can contain whatever of type T.
NotificationMessage(string notification)a message that contains a notification. this might be
used to send a notification to a notification factory that will show the message in the preferred way.
There’s also a NotificationMessage<T>(T notification) should you need it.
The next one is NotificationMessageAction(string notification, Action callback) basically the same as the NotificationMessage but you can add a callback action that will fire once the message is received. This one also has the generic implementation just like NotificationMessage.
DialogMessage(string content, Action<MessageBoxResult> callback)
This message is meant to ask the user to input something and it will return the result of that input in the
MessageBoxResult. MessageBoxResult is an enum that lives in System.Windows
The DialogMessage class inherits from GenericMessage<string>
PropertyChangedMessage(T oldValue, T newValue, string propertyName) The PropertyChangedMessage is meant to use like the RaisePropertyChanged implementation. This is great when multiple
viewmodels need to respond to a changed property.
Be careful when registering listeners, try to use as many different types of messages as makes sense. You don’t want a wrong listener to receive a message because it happens to listen to the same type of message. To register a listener do this:
MVVM Light is available on every XAML based platform. And it comes with a portable version now. The portable version is a separate library on NuGet.
If you decide to use the portable version, make sure that every project in your solution that needs the MVVM Light libraries references the portable version. It does not work together with the “normal” MVVM Light libraries. When you use the PCL version, you can put your viewmodels in a separate, portable library and share them over, for example, a Windows Store and a Windows Phone app.
MVVM Light has an ICommand implementation called RelayCommand that can be used to bind commands to actions. Like for example a button in XAML has a Command property that can be bound to an ICommand on its datacontext, so that when the button is clicked the ICommand will fire. Unfortunately not every XAML UI element has a bindable command property for every event that they can trigger and that’s where EventToCommand comes into play. With EventToCommand you can bind any event from a XAML UI element to an ICommand in the viewmodel.
First we’ll need two namespaces in our XAML page
Let’s say that we want to use the Tap event on a stackpanel.
Line 3 specifies the event that we want to handle, note that this is a string so be aware of typos. Line 4 binds the actual command and can even pass a parameter to the ICommand implementation.
The NavigateAway method has this signature
The parameter will be the word “Edit” in this case as that’s what we’ve specified in the XAML. We can even pass the eventargs from the event to the Command by changing line 4 from the XAML snippet to this
Windows Store applications don’t have these behaviors out of the box so you won’t be able to use EventToCommand there unless you install the Win8nl toolkit from NuGet. Joost Van Schaik has build his own implementation of behaviors in WinRT and thanks to his efforts (and of some other people that have helped in the project) we can now use EventToCommand in WinRT.
Since .net 4.5 we have the await/async keywords and being the good little citizens that we are we do a lot of stuff async now. That means if we want to update something that lives on the UI thread we’ll need the Dispatcher class to marshall our action to that thread. Normally we don’t have access to the Dispatcher from our viewmodel classes. MVVM Light contains a DispatcherHelper that will execute an action on the UI thread when needed.
The DispatcherHelper gets initialized in the App.xaml.cs in the InitializePhoneApplication method (in a WP8 project that is).
DispatcherHelper also has a RunAsync method. The difference with the CheckBeginInvokeOnUI is that the CheckBeginInvokeOnUI will first check if it’s already on the UI thread, if it is it will just execute the action, if it isn’t it will call the RunAsync method.
MVVM Light has complete Blend support, meaning you can drag and drop properties from the viewmodel onto the view to generate a binding, or you can generate design time data based on the datacontext and so on. I’m really not that good in Blend so I’m not going into detail about this one, just remember that MVVM Light was build with Blend in mind.
This one you probably knew but MVVM Light is completely open source. http://mvvmlight.codeplex.com/ is the place to be if you want to dive into the source code.
Laurent Bugnion, the founder of MVVM Light, is on Twitter! https://twitter.com/LBugnion he’s a great guy to chat with and very eager to help out anyone who needs help.
MVVM Light is a great library with a few hidden gems. In this article I’ve discussed 8 very interesting ones that can make your life as a developer easier. I’ve included two more extra items because 10 is a prettier number than 8