Thanks for visiting my blog!
As I wrote and subsequently taught the Silverlight Tour workshop, I’ve had a number of discussions with students, clients and the community-at-large about how to architect Silverlight applications.
The momentum behind the Model-View-ViewModel (MVVM) design pattern makes a lot of sense to me, especially with declarative views (as seen in Silverlight and WPF). Most of my thinking around this was covered in my MSDN article about it:
One topic that the article is thin on is how the View and the ViewModel are related. After the article shipped, I had some lengthy conversations with lots of people about this from John Papa, Laurent Bugnion, Glenn Block, et al. It occurred to me that some of the nomenclature was confusing. The three parts of the MVVM are:
- Model: Responsibile for managing and delivering data.
- ViewModel: Responsible for shaping, sorting and filtering data for a view(s).
- View: Responsible for formatting and displaying data.
The three elements have a clear separation of responsibilities. Typically a small number (or one) model exists in my projects with Views and ViewModels being built in pairs. Though it is not uncommon to build more than one view for a single ViewModel. As long as the separation is there, having two views that show the same data but in very different ways is in keeping with the pattern in my opinion. This can be seen in this simple illustration:
Most what I’ve mentioned in the article and so far in this blog post is what most of the community seems to agree on. The last part of the contention is how do you create Views and ViewModels. The two approaches I hear most often are:
- View-First: The View has a relationship to its ViewModel(usually through data binding).
- ViewModel-First: The ViewModel creates the view (usually through an IoC container).
In View-First, it is usually is exemplified in XAML like so (as I showed in my article):
<UserControl x:Class="MVVM.Client.Views.GameView"
...
xmlns:data="clr-namespace:MVVM.Client.Data;assembly=MVVM.Client.Data">
<UserControl.Resources>
<data:GamesViewModel x:Key="TheViewModel" />
</UserControl.Resources>
<Grid DataContext="{Binding Path=Games,
Source={StaticResource TheViewModel}}">
...
</Grid>
</UserControl>
In ViewModel-First, it is usually implemented using a Inversion of Control container (e.g. Unity, Ninject, Spring, etc.). This way the ViewModel can request the interface (in the constructor) for the View it expects:
public MyViewModel
{
public MyViewModel(IMyView view)
{
}
}
In both of these methods I tend not to like the sticky-ness of the view to the view-model. Also, both of these imply a one-to-one relationship which while the common case, is not the always case.
I have come up with another pattern that I am tentatively calling a “Marriage”. (I don’t love this name but its the closest, non-technobabble name I’ve found for it).
Marrying the View and ViewModel
In my design, I want the View and the ViewModel to be ignorant of each other so that I could mock either side of the equation without impacting the other. In practice, mocking the View-Model is common, but mocking (and testing) the View is not common at all. But by not tying them tightly, it does allow us to move to a one View-Model to multiple Views without any real pain.
In a Marriage, you would simply apply the ViewModel to the View at runtime. This may be done with a class that handles and isolated this or simply with some simple code. For example, I typically have an IView interface that requires a method to do this applicaiton like so:
public interface IView
{
void ApplyViewModel(object viewModel);
}
Then in the module declaration for a module (or assembly) holding the View and ViewModel, I simply use the IoC container to create them (either using Interfaces or class names depending on the complexity of the project) then apply the ViewModel to the View via the interface:
IView view = theContainer.Resolve<IGameView>();
IViewModel vm = theContainer.Resolve<IGameViewModel>();
view.ApplyViewModel(vm);
The magic of this code is that you retain the anonymity while perserving the functionality. It becomes the user of the View/ViewModel’s responsibility to determine how they are related.
I explain this pattern in my article on the Prism Framework and Silverlight coming in next month’s MSDN magazine. Using this pattern with an overall Composition pattern for building your applications has a number of benefits beyond separation of responsibilities and testing.
Just to throw a plug in as well, I also teach this pattern (and Prism) in our Advanced Silverlight Workshop coming to Seattle in August.
Let me know what you think of this versus the View-First or ViewModel-First patterns.