Monday, April 26, 2010

MVVM with Transaction and View Locator Example

I had a lot of requests after both of my posts about transaction with the Model-View-ViewModel (MVVM) pattern and Yet Another View Locator Pattern to provide a sample project. You asked, I listened, and here it is.

I'll walk through how I built the example. Most of the code is taken verbatim from my two previous posts. To make it easier to use the transactions, I created a transaction command:

public class TransactionCommand<T> : ICommand where T : BaseINPC  
{
    private readonly TransactionModel<T> _transaction;
    private readonly bool _forCommit;

    public TransactionCommand(TransactionModel<T> transaction, bool forCommit)
    {
        _transaction = transaction;
        _forCommit = forCommit;

        transaction.Value.PropertyChanged += (o, e) =>
                                                    {
                                                        if (CanExecuteChanged != null)
                                                        {
                                                            CanExecuteChanged(this, EventArgs.Empty);
                                                        }
                                                    };
    }

    public bool CanExecute(object parameter)
    {
        return _transaction.Value.IsDirty; 
    }

    public void Execute(object parameter)
    {
        string message = _forCommit
                                ? "Are you sure you wish to save your changes?"
                                : "Are you sure you wish to cancel? All changes will be lost.";
        var result = MessageBox.Show(message, "Please confirm", MessageBoxButton.OKCancel);
        if (result.Equals(MessageBoxResult.OK))
        {
            if (_forCommit)
            {
                _transaction.Value.IsDirty = false; 
                _transaction.Commit();
            }
            else
            {
                _transaction.Rollback();
            }                
        }
    }

    public event EventHandler CanExecuteChanged;
}

Normally I'd separate the dialog box but this is a "quick and dirty" example so I left it as it is. "If you're not for us, you're against us." Well, not entirely, but this command takes in the object it "listens" to and is either for commit, or for rollback. It will automatically look at the dirty flag on the target model and only enable when set, and then shows the appropriate confirmation before committing, rolling back, or canceling the operation.

With that handy command in place, I can now create a base view model that is typed to a model we will wrap with transactions. It looks like this:

public class ViewModelBase<T> : BaseINPC where T : BaseINPC
{
    private TransactionModel<T> _transaction; 

    public T EditableObject
    {
        get { return _transaction.Value; }
        set
        {
            RaisePropertyChanged(() => EditableObject);
            _Init(value);
        }
    }

    private void _Init(T instance)
    {
        _transaction = new TransactionModel<T>(instance);
        ConfirmCommand = new TransactionCommand<T>(_transaction, true);
        CancelCommand = new TransactionCommand<T>(_transaction, false);
        RaisePropertyChanged(()=>ConfirmCommand);
        RaisePropertyChanged(()=>CancelCommand);
    }

    public ICommand ConfirmCommand { get; set; }

    public ICommand CancelCommand { get; set; }
}

The view model exposes an EditableObject property. When set, it automatically wraps this in a transaction and binds the appropriate confirm and cancel commands.

The typed view model creates a dummy contact record (this is where you would use a service or some other mechanism to fetch the records you will edit):

[ViewModelForType("Contact")]
public class ContactViewModel : ViewModelBase<Contact>
{
    public ContactViewModel()
    {
        var contact = new Contact
                            {
                                FirstName = "Jeremy",
                                LastName = "Likness",
                                Email = "[email protected]",
                                PhoneNumber = "555-1212"
                            };

        contact.IsDirty = false; 
        EditableObject = contact;           
    }
      
}

Yes, the phone number is fake. Notice that I type it to my contact entity and then the only work I need to do is set the EditableObject. By tagging the view model, I can route it to the view which has a corresponding tag. This is what the routing engine looks like. Note I am dealing really with the one circumstance of the contact view, so I hard coded the example to the first item in the list. For a larger application, I'd likely use an ItemsControl with a navigation interface that performs the binding as the views come into focus.

[Export]
public class ViewManager : IPartImportsSatisfiedNotification 
{
    [ImportMany(AllowRecomposition = true)]
    public Lazy<UserControl, IViewForTypeCapabilities>[] Views { get; set; }

    [ImportMany(AllowRecomposition = true)]
    public Lazy<BaseINPC, IViewModelForTypeCapabilities>[] ViewModels { get; set; }

    [Import]
    public ContentControl MainRegion { get; set; }

    public void OnImportsSatisfied()
    {
        if (Views.Length > 0)
        {
            var view = Views[0].Value;
            MainRegion.Content = view;
            var viewModel =
                (from vm in ViewModels where vm.Metadata.TypeName.Equals(Views[0].Metadata.TypeName) select vm.Value)
                    .FirstOrDefault();
            view.DataContext = viewModel; 
        }
    }
}

That's it! With the MEF glue to pull this all together, you get the application below. Notice how you can confirm and then change text and rollback to the original and how it is all handled by the framework - the developer's only concern is simply binding to EditableObject. (Also note I did not wire any validations, but those can easily fire for each field and still not interfere with the transaction model).

Enjoy!

Remember, you can download the full source here.

Jeremy Likness

Friday, April 23, 2010

Yet Another MVVM Locator Pattern

En español — Otro patrón de localización de modelos de vista

Been working with a lot of customers using the MVVM pattern with MEF and the issue always comes up regarding how to marry views to view models. There have a been a few musings on this, from my own ViewModel locator pattern to the even more advanced (and elegant) locator proposed by John Papa et al.

This is another pattern you may find useful. Most of the time your views are used in conjunction with some sort of navigation paradigm, whether it uses the navigation framework provided by Silverlight or a custom region management-type solution. The nice thing about using MEF for these needs is that the Lazy operator ensures the control is not wired up until it is needed. By some simple "magic" if we are using this pattern, we can easily bind the view to the view model in a totally decoupled manner.

First, we simply create a custom attribute for the view and the corresponding interface to make it easy to extract meta-data with MEF:

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ViewOfTypeAttribute : ExportAttribute 
{     
    public string TypeName { get; set; }
    
    public ViewOfTypeAttribute(string typeName) : base(typeof(UserControl))
    {
        TypeName = typeName; 
    }
}

public interface IViewOfTypeCapabilities 
{
    string TypeName { get; }
}

Now we have a "magic string" we can tag the view with. If you like, you can convert it to an enum and have it typed, but this gives us more flexibility for other modules we may not know about. So my contact view might get tagged like this:

[ViewOfType("Contact")]
public partial class ContactView : UserControl
{
   public ContactView() 
   {
      InitializeComponent();
   }
}

Now we just make another tag for our view model. Almost all implementations of MVVM have some sort of base view model to help with things like firing the INotifyPropertyChanged event and so forth. Therefore, it's easy to target an attribute to the view model like this:

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ViewModelOfTypeAttribute : ExportAttribute 
{     
    public string TypeName { get; set; }
    
    public ViewModelOfTypeAttribute(string typeName) : base(typeof(ViewModelBase))
    {
        TypeName = typeName; 
    }
}

public interface IViewModelOfTypeCapabilities 
{
    string TypeName { get; }
}

Look familiar? It should, because that's how we route views to view models. This way, even if multiple views use the same view model, we can still bind them together. When I make my view model, I simply tag it for export like this:

[ViewModelOfType("Contact")] 
public class ContactViewModel : ViewModelBase 
{
}

Notice the string I passed is the same for the view and the view model. These must match for the binding to occur! Now, I'm purposefully leaving out the navigation implementation. There are many ways this might happen, from swapping a ContentControl to using an ItemsControl and simply switching visibility. At some point, you will instantiate a copy of your view. When that happens, you can automatically bind the viewmodel if it is available. Here's a snippet that should give you the general idea:

[Export]
public class Binder  
{
   [ImportMany(AllowRecomposition=true)]
   public Lazy<UserControl,IViewOfTypeCapabilities> Views { get; set; }

   [ImportMany(AllowRecomposition=true)]
   public Lazy<ViewModelBase,IViewModelOfTypeCapabilities> ViewModels { get; set; }

   private _Bind(string binding) 
   {
      var viewModel = (from vm in ViewModels where vm.Metadata.TypeName.Equals(binding) select vm.Value).FirstOrDefault();
      
      foreach(var view in (from v in Views where v.Metadata.TypeName.Equals(binding) select v.Value).ToArray())
      {
         view.DataContext = viewModel;           
      }
   }
}

The _Bind command is simply called the first time the view is loaded onto a surface (added to a control, for example).

Now anytime you need to wire the two together, forget XAML or code behind or any of that nonsense. Just tag the view and the view model with a common attribute and they will get glued together for you!

Jeremy Likness

Thursday, April 22, 2010

Transactions with MVVM

One objection to MVVM I often hear is that it doesn't manage transactions well. I'm not talking about database transactions or "true atomic" transactions, but those short-lived transactions that happen in the UI. With data-binding, updates happen immediately. If I pass a validation, the field is updated.

Many applications, however, don't work this way. While edits and validations exist for the fields, you may often have business logic that has dependencies on multiple entries in the form. If these "composite" validations fail, you want to rollback to the original value. How do we do this with MVVM?

Again, the problem isn't with MVVM, but rather with the implementation. One common approach I've seen is to simply keep a copy of the old data, then swap it out as needed. This works well, but when you have large data models or even a list of items, can get a little ugly. So what can we do?

First, let's build a few basic base classes that most MVVM solutions contain. We want to handle INotifyPropertyChanged, so we'll borrow the elegant code I learned from Rob Eisenberg in his Build your Own MVVM Framework presentation at Mix 2010. I'll also add to that some automatic "dirty" checks (i.e. sets the dirty flag when a property is modified).

public abstract class BaseModel : INotifyPropertyChanged 
{
    public const string IS_DIRTY = "IsDirty";
    public const string IGNORE_DIRTY = "IgnoreDirty"; 

    private bool _isDirty = false; 

    protected BaseModel()
    {
        PropertyChanged += BaseModel_PropertyChanged;
    }

    void BaseModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (!_isDirty && !e.PropertyName.Equals(IS_DIRTY))
        {
            IsDirty = true; 
        }
    }

    public bool IsDirty
    {
        get { return _isDirty; }
        set
        {
            if (!_isDirty.Equals(value))
            {
                _isDirty = value;
                RaisePropertyChanged(() => IsDirty); 
            }
        }
    }

    public void NotifyOfPropertyChange(string propertyName)
    {
        var handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName)));
        }
    }

    public void RaisePropertyChanged<TProperty>(Expression<Func<TProperty>> property)
    {
        if (PropertyChanged == null)
        {
            return; 
        }

        var lambda = (LambdaExpression)property;

        MemberExpression memberExpression;

        if (lambda.Body is UnaryExpression)
        {
            var unaryExpression = (UnaryExpression)lambda.Body;
            memberExpression = (MemberExpression)unaryExpression.Operand;
        }
        else memberExpression = (MemberExpression)lambda.Body;

        NotifyOfPropertyChange(memberExpression.Member.Name);
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Anything that inherits from this has strongly typed property changed events. Furthermore, whenever a property is assigned, it automatically sets the dirty flag for you.

Next, we don't want to do the work of making a deep copy every time we need to save something off, do we? I didn't think so. Let's use an extension method to make it easy to copy anything that derives from the base model. We're going to assume that this contains really just basic value types or simple objects, or other objects that inherit from base model that we can recursively copy:

public static class ModelExtensions
{
    public static T Copy<T>(this T source) where T : BaseModel 
    {
        var clone = Activator.CreateInstance(source.GetType()) as BaseModel;
        return (T)source.Copy(clone);           
    }

    public static T Copy<T>(this T source, T clone) where T : BaseModel
    {
        const string ITEM = "Item";
        const string COUNT = "Count";
        const string ADD = "Add";
            
       
            foreach (PropertyInfo curPropInfo in source.GetType().GetProperties())
            {
                if (curPropInfo.GetGetMethod() != null
                    && (curPropInfo.GetSetMethod() != null))
                {
                    if (!curPropInfo.Name.Equals(ITEM))
                    {
                        object getValue = curPropInfo.GetGetMethod()
                            .Invoke(source, new object[] { });

                        if (getValue != null && getValue is BaseModel)
                        {
                            var baseModel = getValue as BaseModel;
                            getValue = baseModel.Copy();
                        }

                        curPropInfo.GetSetMethod().Invoke(clone, new[] { getValue });                                   
                    }
                    else
                    {
                        var numberofItemInColleciton =
                            (int)
                            curPropInfo.ReflectedType.GetProperty(COUNT)
                                .GetGetMethod().Invoke(source, new object[] { });

                        for (int i = 0; i < numberofItemInColleciton; i++)
                        {
                            object getValue = curPropInfo.GetGetMethod().Invoke(source, new object[] { i });

                            if (getValue != null && getValue is BaseModel)
                                getValue = ((BaseModel)getValue).Copy();

                            curPropInfo.ReflectedType.GetMethod(ADD).Invoke(clone,
                                                                                    new[] { getValue });                                
                        }
                    }
                }
            }        

        return (T)clone;
    }
}    

Depending on how you handle the model, you may want to turn off the dirty flag after the clone operation.

OK, so let's get to the transactions. First, we'll create a simple class that wraps any model in a transaction. What we do is bind to the Value property, and then through our commands or other mechanisms, call Commit and Rollback as needed to apply or reverse changes.

public class TransactionModel<T> where T: BaseModel 
{
    private T _src;
    private T _editable;

    public TransactionModel(T src)
    {
        _editable = src;
        _src = _editable.Copy();
    }

    public T Value
    {
        get { return _editable; }
        set
        {
            _editable = value;
            _src = _editable.Copy();
        }
    }

    public void Commit()
    {
        _editable.Copy(_src);
    }

    public void Rollback()
    {
        _src.Copy(_editable); 
    }

    public override bool Equals(object obj)
    {
        return obj is TransactionModel<T> && ((TransactionModel<T>)obj).Value.Equals(Value);
    }

    public override int GetHashCode()
    {
        return Value.GetHashCode();
    }
}

Note how we take in the initial property and copy it. The commit and rollbacks do not create new objects but transfer properties to and from as needed. If a new value is assigned, we automatically generate the copy and are ready to continue with the transaction.

With this scenario, you can simply wrap your model in a TransactionMode and bind to the Value property. All other operations can reference the original object, it will simply update as needed based on the commits and/or rollbacks.

While this is quite useful, what if you have a large list of items and want to either commit or roll the entire list back? No problem!

public class TransactionCollection<T> where T: BaseModel 
{
    private List<TransactionModel<T>> _transactions; 

    public TransactionCollection(IEnumerable<T> source)
    {
        Collection = new ObservableCollection<T>(source);
        Collection.CollectionChanged += Collection_CollectionChanged;

        _transactions = new List<TransactionModel<T>>(Collection.Count);

        foreach(var t in source)
        {
            _transactions.Add(new TransactionModel<T>(t))
        }
    }

    void Collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.OldItems != null)
        {
            foreach (var item in e.OldItems)
            {
                var transaction = (from t in _transactions where t.Value.Equals(item) select t).FirstOrDefault();
                if (transaction != null)
                {
                    _transactions.Remove(transaction);
                }
            }
        }

        if (e.NewItems != null)
        {
            foreach (var item in e.NewItems)
            {
                _transactions.Add(new TransactionModel<T>((T)item));
            }
        }
    }

    public ObservableCollection<T> Collection { get; private set; }

    public void Commit()
    {
        foreach(var t in _transactions)
        {
           t.Commit(); 
        }
    }

    public void Rollback()
    {
        foreach(var t in _transactions)
        {
           t.Rollback(); 
        }
    }
}

With this helper class, you can bind to the collection with a data grid, list box, or any other control and all that control "sees" is a collection of your objects. However, the wrapper "listens" to items being added/removed and automatically wraps them in a transaction, so you can then commit or rollback the entire list.

As you can see, requiring the ability to rollback is not only fine with MVVM, but also rather easy when you have the right helper classes in place.

Jeremy Likness

Thursday, April 15, 2010

Converting Silverlight 3 to Silverlight 4

In this video, I wanted to share just how quick and easy it is to convert a Silverlight 3 project to Silverlight 4.

The steps are basically as follows:

  • Make sure you have the Silverlight 4 tools
  • If you use Blend or any of the interactivity extensions (for triggers and behaviors) be sure to get the latest version of Blend
  • If you use the Toolkit, download and install the latest version of that as well
  • Open your project in Visual Studio 2010, then
    1. Right-click the Silverlight projects, go into properties and change to target Silverlight 4
    2. Delete any bad Toolkit or Blend references and re-add them to point to the current version
    3. If you used the MEF preview, the references should update automatically — delete any local copies of the DLLs you may have included in the project
    4. Compile and run: in most cases, you're done!

In this simple example, I not only converted the application, but took advantage of the fact that buttons support commanding and removed a trigger I created in order to bind the button directly. Enjoy!

Jeremy Likness

Wednesday, April 14, 2010

Model-View-ViewModel (MVVM) Explained

The purpose of this post is to provide an introduction to the Model-View-ViewModel (MVVM) pattern. While I've participated in lots of discussions online about MVVM, it occurred to me that beginners who are learning the pattern have very little to go on and a lot of conflicting resources to wade through in order to try to implement it in their own code. I am not trying to introduce dogma but wanted to pull together key concepts in a single post to make it easy and straightforward to understand the value of the pattern and how it can be implemented. MVVM is really far simpler than people make it out to be.

Click here to read the Spanish version (Leer en español)


Want to learn about MVVM in the HTML5 age? Watch my course on Mastering AngularJS (click here for a free 15-day trial).

Why Even Care About MVVM?

Why should you, as a developer, even care about the Model-View-ViewModel pattern? There are a number of benefits this pattern brings to WPF, Silverlight, Windows Phone and now Windows 8 app development. Before you go on, ask yourself:
  • Do you need to share a project with a designer, and have the flexibility for design work and development work to happen near-simultaneously?
  • Do you require thorough unit testing for your solutions?
  • Is it important for you to have reusable components, both within and across projects in your organization?
  • Would you like more flexibility to change your user interface without having to refactor other logic in the code base?
If you answered "yes" to any of these questions, these are just a few of the benefits that using the MVVM model can bring for your project.

I've been amazed at some conversations I've read online. Things like, "MVVM only makes sense for extremely complex UI" or "MVVM always adds a lot of overhead and is too much for smaller applications." The real kicker was, "MVVM doesn't scale." In my opinion, statements like this speak to knowledge and implementation of MVVM, not MVVM itself. In other words, if you think it takes hours to wire up MVVM, you're not doing it right. If your application isn't scaling, don't blame MVVM, blame how you are using MVVM. Binding 100,000 items to a list box can be just silly regardless of what pattern you are following.

So the quick disclaimer: this is MVVM as I know it, not MVVM as a universal truth. I encourage you to share your thoughts, experiences, feedback, and opinions using the comments. If you feel something is incorrect, let me know and I'll do my best to keep this post updated and current.

Learn about MVVM and creating code that can be shared between WPF, Silverlight, the Windows Phone, and Windows 8 apps in my book, Building Windows 8 Apps with C# and XAML.

MVVM at a Glance

Let's examine the pieces of the MVVM pie. We'll start with the basic building block that is key for all applications: data and information. This is held in the model.

The Model

The model is what I like to refer to as the domain object. The model represents the actual data and/or information we are dealing with. An example of a model might be a contact (containing name, phone number, address, etc) or the characteristics of a live streaming publishing point.

The key to remember with the model is that it holds the information, but not behaviors or services that manipulate the information. It is not responsible for formatting text to look pretty on the screen, or fetching a list of items from a remote server (in fact, in that list, each item would most likely be a model of its own). Business logic is typically kept separate from the model, and encapsulated in other classes that act on the model. This is not always true: for example, some models may contain validation.

It is often a challenge to keep a model completely "clean." By this I mean a true representation of "the real world." For example, a contact record may contain a last modified date and the identity of the modifying user (auditing information), and a unique identifier (database or persistence information). The modified date has no real meaning for a contact in the real world but is a function of how the model is used, tracked, and persisted in the system.

Here is a sample model for holding contact information:
namespace MVVMExample
{
    public class ContactModel : INotifyPropertyChanged
    {
        private string _firstName;

        public string FirstName
        {
            get { return _firstName; }
            set
            {
                _firstName = value;
                RaisePropertyChanged("FirstName");
                RaisePropertyChanged("FullName");
            }
        }

        private string _lastName;

        public string LastName
        {
            get { return _lastName; }
            set
            {
                _lastName = value;
                RaisePropertyChanged("LastName");
                RaisePropertyChanged("FullName");
            }
        }

        public string FullName
        {
            get { return string.Format("{0} {1}", FirstName, LastName); }
        }

        private string _phoneNumber;

        public string PhoneNumber
        {
            get { return _phoneNumber; }
            set
            {
                _phoneNumber = value;
                RaisePropertyChanged("PhoneNumber");
            }
        }

        protected void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public override bool Equals(object obj)
        {
            return obj is ContactModel && ((ContactModel) obj).FullName.Equals(FullName);
        }

        public override int GetHashCode()
        {
            return FullName.GetHashCode();
        }
    }
}

The View


The view is what most of us are familiar with and the only thing the end user really interacts with. It is the presentation of the data. The view takes certain liberties to make this data more presentable. For example, a date might be stored on the model as number of seconds since midnight on January 1, 1970 (Unix Time). To the end user, however, it is presented with the month name, date, and year in their local time zone. A view can also have behaviors associated with it, such as accepting user input. The view manages input (key presses, mouse movements, touch gestures, etc) which ultimately manipulates properties of the model.

In MVVM, the view is active. As opposed to a passive view which has no knowledge of the model and is completely manipulated by a controller/presenter, the view in MVVM contains behaviors, events, and data-bindings that ultimately require knowledge of the underlying model and viewmodel. While these events and behaviors might be mapped to properties, method calls, and commands, the view is still responsible for handling it's own events and does not turn this completely over to the viewmodel.
One thing to remember about the view is that it is not responsible for maintaining its state. Instead, it will synchronize this with the viewmodel.

Here is an example view, expressed as XAML:
<UserControl x:Class="MVVMExample.DetailView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding CurrentContact}">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBlock Text="Name:" HorizontalAlignment="Right" Margin="5"/>
        <TextBlock Text="{Binding FullName}" HorizontalAlignment="Left" Margin="5" Grid.Column="1"/>
        <TextBlock Text="Phone:" HorizontalAlignment="Right" Margin="5" Grid.Row="1"/>
        <TextBlock Text="{Binding PhoneNumber}" HorizontalAlignment="Left" Margin="5" Grid.Row="1" Grid.Column="1"/>
    </Grid>
</UserControl>

Note that the various bindings are the integration/synchronization points with the viewmodel.

The ViewModel (Our Controller/Presenter)

The viewmodel is a key piece of the triad because it introduces Presentation Separation, or the concept of keeping the nuances of the view separate from the model. Instead of making the model aware of the user's view of a date, so that it converts the date to the display format, the model simply holds the data, the view simply holds the formatted date, and the controller acts as the liaison between the two. The controller might take input from the view and place it on the model, or it might interact with a service to retrieve the model, then translate properties and place it on the view.

The viewmodel also exposes methods, commands, and other points that help maintain the state of the view, manipulate the model as the result of actions on the view, and trigger events in the view itself.
MVVM, while it evolved "behind the scenes" for quite some time, was introduced to the public in 2005 via Microsoft's John Gossman blog post about Avalon (the code name for Windows Presentation Foundation, or WPF). The blog post is entitled, Introduction to Model/View/ViewModel pattern for building WPF Apps and generated quite a stir judging from the comments as people wrapped their brains around it.

I've heard MVVM described as an implementation of Presentation Model designed specifically for WPF (and later, Silverlight).

The examples of the pattern often focus on XAML for the view definition and data-binding for commands and properties. These are more implementation details of the pattern rather than intrinsic to the pattern itself, which is why I offset data-binding with a different color:

Model-View-ViewModel
Here is what a sample view model might look like. We've created a BaseINPC class (for "INotifyPropertyChanged") that has a method to make it easy for raising the property changed event.

namespace MVVMExample
{
    public class ContactViewModel : BaseINPC
    {
        public ContactViewModel()
        {
            Contacts = new ObservableCollection<ContactModel>();
            Service = new Service();
            
            Service.GetContacts(_PopulateContacts);

            Delete = new DeleteCommand(
                Service, 
                ()=>CanDelete,
                contact =>
                    {
                        CurrentContact = null;
                        Service.GetContacts(_PopulateContacts);
                    });
        }

        private void _PopulateContacts(IEnumerable>ContactModel> contacts)
        {
            Contacts.Clear();
            foreach(var contact in contacts)
            {
                Contacts.Add(contact);
            }
        }

        public IService Service { get; set; }

        public bool CanDelete
        {
            get { return _currentContact != null; }
        }

        public ObservableCollection<ContactModel> Contacts { get; set; }

        public DeleteCommand Delete { get; set; }

        private ContactModel _currentContact;

        public ContactModel CurrentContact
        {
            get { return _currentContact; }
            set
            {
                _currentContact = value;
                RaisePropertyChanged("CurrentContact");
                RaisePropertyChanged("CanDelete");
                Delete.RaiseCanExecuteChanged();
            }
        }
    }
}

This view model is obviously designed to manage a list of contacts. It also exposes a delete command and a flag to indicate whether delete is allowed (thus maintaining state for the view). Often the flag would be part of the command object, but the example is in Silverlight 3 which does not have native support for command binding, and I wanted to show a simple solution that didn't require a fancy framework. (Take a look at this video to see how easy it is to convert the example from Silverlight 3 to Silverlight 4 and use native commanding instead). The view model here makes a concrete reference to the service.

For larger applications, I prefer to wire in that reference externally or use a dependency injection framework. What's nice is we have the flexibility to build it like this initially and then refactor as needed - again, you do not have to use any of these frameworks to take advantage of the pattern, as you can see from this example. It fetches the list of "contacts" right away, which is a hard-coded list of me and someone a little more popular. The phone numbers, of course, are faked.

Let's get a little more specific and look at how this would be implemented in a sample application. Here is what an X-ray of a sample MVVM set up may look like:

MVVM Explained

So what can we gather from this snapshot?

First, the IConfig represents a configuration service (in a newsreader it may contain the account information and feeds that are being fetched), while the IService is "some service" - perhaps the interface to fetch feeds from RSS sources in a news reader application.

The View and the ViewModel
  • The view and the viewmodel communicate via data-binding, method calls, properties, events, and messages
  • The viewmodel exposes not only models, but other properties (such as state information, like the "is busy" indicator) and commands
  • The view handles its own UI events, then maps them to the viewmodel via commands
  • The models and properties on the viewmodel are updated from the view via two-way databinding
Two mechanisms that often factor into implementations of the pattern are triggers (especially data triggers) in WPF, and the Visual State Manager (VSM) in Silverlight. These mechanisms help implement the pattern by binding UI behaviors to the underlying models. In Silverlight, the VSM should be the primary choice for coordination of transitions and animations. Justin Angel has a fairly comprehensive post on it: Learn more about VSM. I also have a slide deck with a sample project here.

The ViewModel and the Model

The viewmodel becomes wholly responsible for the model in this scenario. Fortunately, it's not alone:
  • The viewmodel may expose the model directly, or properties related to the model, for data-binding
  • The viewmodel can contain interfaces to services, configuration data, etc in order to fetch and manipulate the properties it exposes to the view
The Chicken or the Egg?

You might have heard discussion about view first or viewmodel first. In general, I believe most developers agree that a view should have exactly one viewmodel. There is no need to attach multiple viewmodels to a single view. If you think about separation of concerns, this makes sense, because if you have a "contact widget" on the screen bound to a "contact viewmodel" and a "company widget" bound to a "company viewmodel", these should be separate views, not a single view with two viewmodels.

A view may be composed of other views, each with its own viewmodel. Viewmodels might compose other viewmodels when necessary (often, however, I see people composing and aggregating viewmodels when in fact what they really want is messaging between viewmodels).

While a view should only have one viewmodel, a single viewmodel might be used by multiple views (imagine a wizard, for example, that has three views but all bind to the same viewmodel that drives the process).

View First

View first simply means the view is what drives the creation or discovery of the view model. In view first scenarios, the view typically binds to the view model as a resource, uses a locator pattern, or has the view model injected via MEF, Unity, or some other means. This is a very common method for managing views and view models. Here are some of my posts on the topic:
The example I've included with this post is view-first. The view is created, then the view model attached. In the App object, it looks like this:
private void Application_Startup(object sender, StartupEventArgs e)
{
    var shell = new MainPage();
    shell.LayoutRoot.DataContext = new ContactViewModel();
    RootVisual = shell;
}

In this example, I'm keeping it simple and not using any frameworks to wire in interfaces and implementations.

ViewModel First

ViewModel first is another method to wire the framework together. In this scenario, the viewmodel is responsible for creating the view and binding itself to the view. You can see an example of this in Rob Eisenberg's convention-based framework he discussed at MIX: Build your own MVVM Framework.

The take away here is there are multiple ways to skin the cat.

A Basic MVVM Framework

In my opinion, a basic MVVM framework really only requires two things:
  1. A class that is either a DependencyObject or implements INotifyPropertyChanged to fully support data-binding, and
  2. Some sort of commanding support.
The second issue exists in Silverlight 3 because the ICommand interface is provided, but not implemented. In Silverlight 4 commanding is more "out of the box." Commands facilitate binding of events from the view to the viewmodel. These are implementation details that make it easier to use the MVVM pattern.

Keep in mind there is very rich support for binding and behaviors in Blend and the free Blend SDK. You can watch my video, MVVM with MEF in Silverlight, to get an idea of how easy it really is to implement the MVVM pattern even without an existing framework in place. The post, MEF instead of Prism for Silverlight 3, shows how to build your own command objects.

With this example, I created a base class to handle the property changed events:
namespace MVVMExample
{
    public abstract class BaseINPC : INotifyPropertyChanged  
    {
        protected void RaisePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged; 

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

I also implemented a command. Typically you would have a more generic type of command to handle different situations, but again, for the sake of illustration, I simply created a delete command specific to the function it performs. I am using a message box to confirm the delete. If you require something more elegant like a ChildWindow, read the scenarios I describe below to better understand how to integrate a dialog box as a service within MVVM.
namespace MVVMExample
{
    public class DeleteCommand : ICommand 
    {
        private readonly IService _service;
        private readonly Func<bool> _canExecute;
        private readonly Action<ContactModel> _deleted;

        public DeleteCommand(IService service, Func<bool> canExecute, Action<ContactModel> deleted)
        {
            _service = service;
            _canExecute = canExecute;
            _deleted = deleted;
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute();
        }

        public void Execute(object parameter)
        {
            if (CanExecute(parameter))
            {
                var contact = parameter as ContactModel; 
                if (contact != null)
                {
                    var result = MessageBox.Show("Are you sure you wish to delete the contact?",
                                                              "Confirm Delete", MessageBoxButton.OKCancel);

                    if (result.Equals(MessageBoxResult.OK))
                    {
                        _service.DeleteContact(contact);
                        if (_deleted != null)
                        {
                            _deleted(contact);
                        }
                    }
                }
            }
        }

        public void RaiseCanExecuteChanged()
        {
            var handler = CanExecuteChanged;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }

        public event EventHandler CanExecuteChanged;
    }
}

This particular command uses a delegate to callback when it is done, but this would only allow for a single subscriber. A multicast delegate or event will be required if multiple consumers (or viewmodels) for the command exist.

In Silverlight 4, I can simply bind a button to the command using the Command tag. I built the example in Silverlight 3, which does not have native support. To create the binding, I made a simple trigger - again, specific to this project and for the sake of illustration - to invoke the command, so I can easily bind it in the XAML.

For the examples I've provided here, you can view the sample application. It is very simple and contains exactly one service and one view model with a "mock database." Two views bind to the same viewmodel, and you can click on a contact to see its details. You can also delete a contact.
I often receive complaints that blog examples are too simple. This is sufficiently complex to show a full app without depending on other frameworks, but certainly doesn't show multiple pages and types of views. The reason you don't see these as often from me is simply because I am a consultant and contractor, so I am constantly building these line of business frameworks and applications for customers, and am not at liberty to share their code. While I can build small examples for posts, I simply don't have the time to build a larger working model. It's something I'd certainly like to do, but just wasn't practical for the timing of this post.

You can download the source code for this example here.

You can also see it in action here (click on the names and try delete ... I simulated a slight delay for the initial load and the refresh after a delete).



I think the easiest way to learn the pattern is by seeing a full application being built. I demonstrate this in MVVM with MEF in Silverlight. In that video, I build some simple viewmodels and show a view that is dynamically swapped based on user selection, and use MEF to wire everything up. A more complex scenario is then introduced in Part 2.

So what about those more complicated line of business solutions ... the ones that actually have more than one button, multiple views, and complex logic? That is beyond the scope of this post to cover in detail, but I'd like to tackle a few common scenarios and how I've solved them with MVVM.

Common MVVM Scenarios

If you're still not sold on how simple MVVM can be, I've got a few "recipes" for scenarios you may encounter. You'll also want to watch the video where I build an RSS feed reader in 30 minutes from scratch to demonstrate the power of MVVM.

In my experience, the idea of binding both commands and models or properties is straightforward. It's when you hit specific situations such as showing a dialog box or triggering an animation that MVVM may seem confusing. How do we solve these common problems?

List with Selection

How do you handle a combo box used for selection of a single, or multiple, items with MVVM? It's actually fairly straightforward. In fact, imagine a scenario where you have a combo-box that has a list of contact names, and another view on the same page that shows the contact details when selected. The ViewModel would look something like this, assuming I'm using MEF to wire dependencies (to show you a different way from the reference application):
public class ContactViewModel : BaseViewModel, IPartImportsSatisfiedNotification
{
    [Import] 
    public IContactService Service { get; set; }

    public ContactViewModel()
    {
       Contacts = new ObservableCollection<Contact>();
    }

    public ObservableCollection<Contact> Contacts { get; set; }

    private Contact _currentContact; 

    public Contact CurrentContact 
    { 
       get { return _currentContact; } 
       set
       {
          _currentContact = value;
          RaisePropertyChanged("CurrentContact"); 
       } 
    }

    public void OnImportsSatisfied() 
    {
       Service.FetchContacts(list =>
          {
             foreach(var contact in list)
             {
                Contacts.Add(contact);
             }
             CurrentContact = Contacts[0];
          });
    }
}

In this case, we import a service for getting contacts, wire in the list and set the current contact. The drop down binds to the Contacts collection. What's important, however, is that the selected item is also bound (this is where the view model maintains state). The binding would look like this:
...
<ComboBox ItemsSource="{Binding Contacts}" SelectedItem="{Binding CurrentContact,Mode=TwoWay}"/> 
...

This ensures whenever something is selected in the list, the current contact is updated. Remember that I mentioned multiple views might share the same viewmodel? In this case, the view for the contact details can use this same view model, and simply bind to the CurrentContact property.

Navigation

Navigation is a common issue to tackle. How do you manage navigation from an MVVM application? Most examples show only a single button or widget on the screen and don't tackle composite applications with multiple pages.

The short answer is that regardless of how you navigate (whether you use your own engine to pull in views, you use the navigation framework supplied by Silverlight, you use region management with Prism or a combination of all of these), you should abstract the mechanism behind an interface. By defining INavigation or something similar, navigation no longer becomes an MVVM problem. However you solve it, your viewmodel can import INavigation and simply navigate to or trigger the transition as needed.
My post on MEF instead of Prism shows how to do this with the Managed Extensibility Framework. Auto-discoverable views using a fluent interface covers mapping views to regions, and Dynamic module loading with Prism has a full solution using the navigation framework. In my own framework, you can read about
navigation here.

Dynamic Modules

This follows navigation. What if you have an extremely large application? It often doesn't make sense to load everything at once. You want the main menu and screne to appear, and then load other modules dynamically as they are needed. This cuts down on the initial time to get the application up and running, and also respects the user's browser and/or desktop memory and CPU.

The issue of dynamic modules isn't really specific to MVVM, but messaging between viewmodels and across modules is of course important. For these, I do believe it makes more sense to look at existing frameworks like MEF and Prism that solve the specific issue. Prism has modules that can be loaded "on demand," and MEF offers a deployment catalog that allows for dynamic loading of XAP files. Prism's solution for messaging across the application is the event aggregator. I talk more about frameworks and solutions for these types of problems in the appendix when I cover existing frameworks that are available to use "out of the box." Read about static and dynamic module management in Jounce.

Dialog

A common UI pattern is the dialog box (similar to the message box, but expects a reply). I've seen a few people trip over how this can be implemented using both MVVM and the restriction by Silverlight that all code must be asynchronous.

The easiest solution in my opinion is to abstract the dialog behind an interface and provide a callback for the response. The view model can import the dialog, then based on some change in state or a command, trigger the dialog service. The callback will return the response and then the view can process accordingly.

For a fuller explanation, read Simple Dialog Service in Silverlight.

Animations

This is a very common problem to tackle: how can changes triggered either in the UI or the backend kick off animations and other transitions?

There are several solutions to the problem. Here are a few examples of how to solve the problem:
  • The Visual State Aggregator allows you to bind animations based on UI events without involving the viewmodel at all. When you do need to involve it, something like
  • Animation delegates can do the trick. Want something more abstract? Try
  • nRoute's reverse ICommand implementation, or
  • Jounce provides view model access to the visual state manager along with behaviors and triggers for the visual state aggregator — you can read more here.
Configuration or Global Values

Another issue I see raised quite often is how to deal with global variables and configuration information. Again, this is less an MVVM problem and more a general architecture consideration. In most cases, you can expose configuration with an interface (IConfiguration) and then wire up an implementation with your configuration values. Any viewmodel that requires the information simply imports the implementation, whether via MEF, Unity, or some other mechanism, and only one copy of the class is kept (Singleton pattern, although most likely managed by the container and not the class itself).

Asynchronous Processes

One point of confusion with Silverlight is that it forces service calls to be asynchronous. This can seem strange when building a viewmodel: when do you trigger the call, and how do you know it is complete? Typically, this is managed by registered to an event when the process is complete, and binding the results. I prefer to hide the implementation details of the events behind a simple Action function. Read Simplifying Asynchronous Calls in Silverlight using Action for an example of this.

Sometimes you may have a more complex workflow that requires multiple asynchronous calls to execute and complete prior to continuing. If that is the case, you might want to look into a mechanism for making it easy to code and read the sequential workflow. This post will help you understand one solution using coroutines, and this post describes how to use an existing robust framework to manage those calls with thread safety, error handling, and more.

Huge Datasets

Finally, I've heard claims that MVVM doesn't handle large datasets well. I would argue it is certain implementations that have this issue, not the pattern itself. The solution is often to page the data, but I find many people approach the problem incorrectly. For some reason, developers want to insist paging is a function of the database and should be isolated to the data access layer. The simple fact that you have a UI element with "current page" and "total pages" suggested it is not just an artifact of the database, but participates in all layers of the application and should be managed as such.

In the most primitive form, you can create a collection that grows as the user pages. If your data is small, you might pull a very large collection and keep it in the Silverlight client, but use a virtualized panel to display the information (the problem with some panels is that they create a control for every bound data element, which can crush performance - virtualized panels only create enough controls to fill the visible window on the screen).

Technologies like WCF RIA support LINQ queries. These queries contain extension methods that allow you to grab only the first few items in a list, rather than fetching the full list at once. The framework also provides helper classes like the PagedCollectionView to help filter, sort, and page data.

What MVVM Isn't

No discussion would be complete unless we talked about what MVVM isn't.

MVVM isn't a complete framework. It's a pattern and might be part of a framework, but it's only a piece of the overall solution for your application architecture. It doesn't address, and doesn't really care, about what happens on your server or how your services are put together. It does stress separation of concerns, which is nice.

I bet that nowhere in this article did you read a rule that stated, "With MVVM, code behind is not allowed." This is a raging debate but the pattern itself doesn't tell you how to implement your view, whether that is with XAML, code-behind, or a combination of the two. I would suggest that if you are spending days writing something just to avoid minutes of code-behind, your approach is wrong.

It is not required for Silverlight or WPF. I believe that line-of-business, data-driven, and forms-based applications are prime candidates for MVVM. Games, entertainment websites, paint programs, and others may not make sense. Be sure you are using the right tool for the right job.

MVVM is not supposed to slow you down! All new patterns and frameworks come with a learning curve. You'll have to accept that your developers need to learn and understand the pattern, but you should not accept that your entire process suddenly takes longer or becomes delayed. The pattern is useful when it accelerates development, improves stability and performance, reduces risk, and so forth. When it slows development, introduces problems and has your developers cringing whenever they hear the phrase, "design pattern" you might want to rethink your approach.

Conclusion

Want to learn about MVVM in the HTML5 age? Watch my course on Mastering AngularJS (click here for a free 15-day trial).

OK, we're done! That's it. I hope you've learned why MVVM is so powerful for Silverlight, WPF, Windows Phone and Windows 8 applications, what the pattern looks like and even examples of solutions for common problems that MVVM can solve. Read more about testing and cross-platform MVVM development in Building Windows 8 Apps with C# and XAML. Now, what are your thoughts and comments?

Jump to Appendix A: Historical Patterns

Jump to Appendix B: Existing Frameworks

A very special thanks to the community members who took time out of their busy schedules to review and provide preliminary feedback and suggestions for this article: (in alphabetical order)
Appendix A: Some Historical Patterns

Model-View-Controller (MVC)

This software architecture pattern was first described in the context of Smalltalk at Xerox in 1979. If you are interested, you can download some of those original papers (PDF format) by clicking here (PDF).

Model-View-Controller (MVC)

Model-View-Presenter (MVP)

In 1996, the Model-View-Presenter pattern (PDF) was introduced to the world. This pattern builds on MVC but places special constraints on the controller, now called the presenter. A general overview looks like this:

Model-View-Presenter

Martin Fowler describes this pattern with two flavors: the Supervising Controller/Presenter and the Passive View. Here is how Microsoft describes: MVP.

Presentation Model

In 2004, Martin Fowler published his description of the Presentation Model. The summary is quite succinct: "Represent the state and behavior of the presentation independently of the GUI controls used in the interface." As you can see, MVVM is a specialized form of this pattern:

Presentation Model

Appendix B: Pre-existing MVVM Frameworks

Now that we have an idea of what MVVM is all about, you don't have to re-invent the wheel. There are a number of out of the box frameworks that exist which implement MVVM. In no particular order:

Jounce MEF and MVVM Guidance

Jounce is my own framework. I developed it to provide guidance for using the Managed Extensibility Framework (MEF) and the MVVM pattern in Silverlight. There is a comprehensive series of blog posts on Jounce, documentation, and a set of quick starts. Jounce provides most services you will need, including: region management, navigation, view model services, routing between views and view models, commands, dynamic XAP loading, and more.

The MVVM Light Toolkit

This is a very popular toolkit that contains support out of the box for base viewmodels, commands, messaging, and project templates to get started. It supports both WPF and Silverlight projects.

SilverlightFX

The stated goals for this framework are to enable concise declarative specification of user interfaces, enable easier separation of view and code, and provide a lean framework.

Caliburn

Caliburn is a popular viewmodel-first framework that supports both WPF and Silverlight. More than just MVVM, however, it is a full application framework.

Cinch

Cinch is a fully featured WPF MVVM framework that makes it easier to develop rich MVVM WPF applications. It also provides UI services/threading/unit tests helpers and much more.

nRoute

Another MVVM framework, this library is unique for the "reverse commands" that allow binding commands to events in the view as opposed to having the view simply send commands to the viewmodel.

MicroModels

A very lean and lightweight approach to MVVM.

Composite WPF/Prism

Despite the name, this framework supports both WPF and Silverlight. It provides reference MVVM implementations and quickstarts, along with support and guidance for composing applications including commands, event aggregation, region management, and more.

While this is certainly not an exhaustive list by any stretch of the imagination, hopefully it gives you an idea of the open source community support available for MVVM and that there are existing mature frameworks that you can choose from to accelerate your development.

Jeremy Likness

Tuesday, April 6, 2010

Ten Reasons to use the Managed Extensibility Framework

Leer: Diez razones para usar MEF.

One question I'm commonly asked is, "Why do I need the Managed Extensibility Framework? How do I know when to use it?" In addition to that really being two questions, I'm not sure I can tell you the top ten reasons to use MEF or whether or not it is the right tool for you. Instead, as a hands-on consultant who has been using MEF in production applications since the earlier previews, I can share ten reasons why I've used it in my development projects and prefer it over over other frameworks.

If you can relate to these ten items and are interested in learning more, check out my video series, Fundamentals of the Managed Extensibility Framework. Click the link to preview the lessons and learn more!

Reason One: It's out of the box.

While much of my work with MEF has been using the previews in Silverlight 3 projects, MEF is not just another side project or add-on. MEF will be part of the .NET Framework 4.0 Common Language Runtime (CLR). Just as we've grown accustomed to using generic lists or sending mail with the SmtpClient class, the Managed Extensibility Framework will be there, in the framework, out of the box. Developers will be able to simply include the namespace and go to work. No additional installs or grief over whether or not to include the bits with the application and worry about versions. It's an intrinsic part of the .NET framework which I believe will lead to fast adoption for the myriad problems it solves. I always prefer to use what is already there when I can, rather than tacking on third-party solutions unless they are absolutely needed.

Reason Two: Dependency injection and inversion of control.

This is the part that seems to confuse people when they ask, "Do we need another Unity?" MEF is far more than a substitute for dependency injection or inversion of control. However, it does manage DI and IoC quite well. With Unity, for example, I had to wire in a bootstrapper and configure the container, then either grab objects from the container to take advantage of constructor injection or explicitly request objects.

In MEF, the parts model makes it far easier in my opinion. I simply make IFoo available:

...
[Export(typeof(IFoo))]
public class Foo {}
...

And then ask for IFoo, and I'm practically done!

...
public class Bar 
{
   [Import]
   public IFoo Foo { get; set; }
}

I find this far easier to set up and manage consistently across large applications than worrying about when/where/how the container has been configured, whether or not I'm using a nested container, and then how to grab the desired implementation.

It also makes testing a breeze. I don't believe in unit testing multiple layers at the same time - if I'm testing Bar, I'm not going to test Foo again. So in this case, I can just set IFoo to a mock object and focus on Bar.

Reason Three: Lifetime management.

By default, imports will provide me with the same (shared) copy of classes that are exported by MEF. I'm not locked into this, however. I can easily override the lifetime of a class using a PartCreationPolicy. This is very important to me because often classes become mangled in order to support patterns like the singleton pattern: you have to hack the constructor and make it private, then supply a public method, and make all of this work in concert with your interface.

With MEF, I simply build a class and don't build lifetime management into the behavior of the class. Should the class know or care if it will live as a single copy, or have multiple copies running around? In most cases, the answer is, "No."

Reason Four: Configuration.

A side effect of lifetime management is that MEF gives me a very easy way to manage configuration information. I've seen it done many ways. In Silverlight, for example, you might be tempted to write a static class or even add properties to the main Application class to hold application-wide configuration data. To me, mangling the application itself in order to support this is wrong.

With MEF, I can simply implement an IConfiguration interface and import it wherever I need it. If I'm writing WPF or ASP.NET code, it's a simple matter in the implementation to parse an app.config or web.config file to load up the values. The consumers of this information, however, don't have to know (and quite frankly, don't care) how it got there. I have a setting for number of threads? Great, I import my IConfiguration and read that property. Done deal.

This is also great for testing, because I can supply an alternate configuration for my test environment.

Reason Five: Factories with dependency resolution.

This ties back to the part creation policies. One powerful feature of MEF is the concept of an ExportFactory. Unlike a direct import, an import of ExportFactory<T> doesn't give me T, but instead gives me a way to create T. This is important if I have a class that might get created multiple times.

If the class has dependencies, such as the configuration information I gave in the previous point, we need MEF to import and satisfy those dependencies. With the export factory, I can do this:

...
[Import]
public ExportFactory<IContract> Factory { get; set; }

public IContract MakeANewContract()
{
   return Factory.CreateExport().Value; 
}
...

Each time I make a new contract, all of the dependencies are wired in for me, so I don't have to worry about loading up the constructor or walking the dependency tree. MEF does it for me. For an example of this, take a look at my blog post Sequential Asynchronous Workflows using Co-routines (the view factory to "make" squares follows this pattern, as it must import the random number service).

Reason Six: ImportMany.

A common pattern in Silverlight and WPF applications is to have a region for some functionality, and then page through multiple controls within that region. For example, a wizard might occupy the main region of the page but actually use four different controls for each of four different steps in the wizard. MEF makes it easy to handle this pattern using ImportMany. I can ask for an IWizard and then retrieve a list of controls that satisfy the interface.

Another example is chain of responsibility and pipeline. The "weak link" in the chain is often that first "bootstrapper" class that has to wire in all of the links in the pipeline or chain of responsibility. The common implementation of this pattern is to have each link process and then conditionally pass processing along to the next link.

With MEF, I can easily import many instances of ILink and then either chain them together or use an iterator or other means to walk through the processes. Adding a new link is as simply as building the implementation, then exporting the class.

These are just a few examples of how powerful the ability to have multiple imports is.

Reason Seven: Strongly typed Metadata.

Of course, you might want to call classes in a particular order. Perhaps you export user controls and use an enumeration to specify where on the screen it belongs. Whatever your needs are, MEF allows you to supply strongly-typed metadata for your exports.

For an example of this, take a look at MEF instead of Prism for Silverlight. There I use the metadata to specify the types of views and regions, then wire them together using the region management pattern introduced by Prism.

Metadata can provide initialization information, routing information, and even priority information. For the Vancouver Winter Olympics, I built a synchronization tool that would scan primary and failover servers for live streaming. The tool generated lists of mismatched and/or missing files so the team at Microsoft could quickly react to ensure the integrity of the failover cluster and guarantee uptime. The tool created an XML document with the changes, then passed the document through a pipeline of modules. One module persisted the file to disk and updated a manifest. Another module would generate a CSV file, and yet another could email the document if certain alert criteria were met. I used MEF to pull in the modules, and metadata to tag the priority (for example, I wanted to persist the file to disk before specifying it as an attachment in the email program, so the module that saved the file had a higher priority than the module that would email it). When I needed another module, such as in testing, it was as simple as building it and exporting it to inject it into the pipeline.

Reason Eight: Extensibility.

MEF is unique in that it is designed specifically for extensibility. Many Dependency Injection/Inversion of Control solutions are designed to help you wire up what you know - "I have this instance, map it to this interface." MEF is designed to help you wire up what you don't know. It is extensible by nature and contains features such as stable composition that ensure your application can safely extend in realtime.

As an example (and for a fast introduction to MEF if this is new to you) take a look at my video, Build a Plug-in Architecture in Under 10 Minutes. I demonstrate building a console application using MEF. After I have the application running, I build a plugin, drop it into the target directory, and show how the application is able to pull in the new plugin in realtime without restarting. Now that's powerful!

Reason Nine: Modularity.

Along with extensibility comes modularity. This is especially important for Silverlight applications. Because these run in the user's browser, developers must take care to minimize the size of the file download as well as the client footprint. You don't want an application that takes 15 minutes to download or maxes out your customer's memory and CPU.

MEF allows for modularity by allowing you to separate functionality into different modules and load them dynamically as needed. This is done via the DeploymentCatalog. Imagine a large application that has ten menu items, but users typically may only go into one. This was the case for our Winter Olympics application that helped the Microsoft team monitor their environment. At any given time they might be pushing a configuration file, monitoring the live streaming servers, or performing other functions within the tool that were not interdependent on each other.

Instead of loading everything and having a huge XAP file, MEF allows you to split your applications into modules that load on demand. Only when the user needs a piece of functionality will their browser download the extension and make it available. This allows them to get up and running faster and conserves resources by only supplying what is needed.

Take a look at MEF instead of Prism for Silverlight Part 1 for an example of dynamic module loading.

Reason Ten: Customization.

Finally, I prefer MEF because it allows for customization. All of the parts are available to extend or customize as needed. Perhaps you are a fan of convention-based configuration and would rather use a provider-based model to wire in dependencies. It can be done.

I develop in Silverlight and am a fan of creating reusable behaviors to avoid duplicating code-behind or overloading view models where it's not needed. With MEF, this is very easy and straightforward. Take a look at Custom Export Providers with Custom Metadata for Region Management as an example. Using metadata, I wanted to take regions and route views similar to how Prism does it. Because MEF is extensible and customizable, I was easily able to build a behavior that would allow me to tag regions and export them with strongly-typed meta data in the XAML.

Of course, the customization doesn't stop there. Take a look at the MEF Visualizer Tool that can be injected into your project and generate DGML to visualize the MEF parts. Now that's powerful!

Conclusion

I'll conclude by saying that I'm very biased toward MEF. For good reason: I've been using it in enterprise applications and it has enabled me to build more composite, extendable, testable, and scalable applications faster and, in my opinion, better. If you're sitting on the fence wondering how MEF compares to other frameworks, I hope this guide will help you decide just how powerful it can be and how it might better fit your needs.

Please share your comments and feedback below. I'd especially love to hear if you are currently working on a MEF project and would like to share how it has helped (or perhaps hindered) you in the process. Thanks!

Jeremy Likness