title: WPF Caliburn MEF application & DI
body: <p>I'm experimenting with using Caliburn and MEF in a WPF application. My MEF knowledge is sketchy at best. </p>
  
  <p>Here's the Bootstrapper:</p>
  
  <pre><code>class Bootstrapper : BootstrapperBase
  {
    public Bootstrapper()
    {
       Initialize();
    }
  
    protected override void OnStartup(object sender, StartupEventArgs e)
    {
       DisplayRootViewFor&lt;IShell&gt;();
    }
  
    protected override void Configure()
    {
       //An aggregate catalog that combines multiple catalogs  
       var catalog = new AggregateCatalog();
  
       //Adds all the parts found in the same assembly as the Program class  
       catalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));
  
       //Create the CompositionContainer with the parts in the catalog  
       container = new CompositionContainer(catalog);
  
       var batch = new CompositionBatch();
       batch.AddExportedValue&lt;IWindowManager&gt;(new WindowManager());
       batch.AddExportedValue&lt;IEventAggregator&gt;(new EventAggregator());
       batch.AddExportedValue(container);
  
       container.Compose(batch);
    }
  
    protected override object GetInstance(Type serviceType, string key)
    {
       string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key;
       var exports = container.GetExportedValues&lt;object&gt;(contract);
  
       if (exports.Any())
          return exports.First();
  
       throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
    }
  
    protected override IEnumerable&lt;object&gt; GetAllInstances(Type serviceType)
    {
       return container.GetExportedValues&lt;object&gt;(AttributedModelServices.GetContractName(serviceType));
    }
  
    protected override void BuildUp(object instance)
    {
       container.SatisfyImportsOnce(instance);
    }
  </code></pre>
  
  <p>}</p>
  
  <p>Here's the shellview:</p>
  
  <pre><code>&lt;Window x:Class="MefCaliburn.ShellView"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:local="clr-namespace:MefCaliburn"
      mc:Ignorable="d"
      Title="ShellView" Height="300" Width="300"&gt;
  &lt;Grid&gt;
      &lt;Grid.RowDefinitions&gt;
          &lt;RowDefinition Height="20"/&gt;
          &lt;RowDefinition/&gt;
          &lt;RowDefinition Height="100"/&gt;
      &lt;/Grid.RowDefinitions&gt;
  
      &lt;ContentControl Grid.Row="0" x:Name="Menu"&gt;&lt;/ContentControl&gt;
      &lt;ContentControl Grid.Row="1"&gt;&lt;/ContentControl&gt;
      &lt;ContentControl Grid.Row="2" x:Name="Messages"&gt;&lt;/ContentControl&gt;
  
  &lt;/Grid&gt;
  </code></pre>
  
  <p></p>
  
  <p>The IShell interface:</p>
  
  <pre><code>public interface IShell
  {
  }
  </code></pre>
  
  <p>Here's my shell view model:</p>
  
  <pre><code>namespace MefCaliburn
  {
  [Export(typeof(IShell))]
  public class ShellViewModel : PropertyChangedBase, IShell
  {
    private readonly IEventAggregator _events;
  
    UserViewModel uvm;
  
    [ImportingConstructor]   
    public ShellViewModel(MenuViewModel menu, MessagesViewModel mess, IEventAggregator eventaggregator)
    {
       Messages = mess;
       Menu = menu;
       _events = eventaggregator;
    }
  
    public MessagesViewModel Messages
    {
       get; set;
    }
  
    public MenuViewModel Menu
    {
       get; set;
    }
  
    public void LaunchUserViewModel()
    {
       uvm = new UserViewModel();
    }
  }
  }
  </code></pre>
  
  <p>So when the Boostrapper overridden method</p>
  
  <pre><code>  protected override void OnStartup(object sender, StartupEventArgs e)
    {
       DisplayRootViewFor&lt;IShell&gt;();
    }
  </code></pre>
  
  <p>gets called, my ShellViewModel constructor is called and the <em>Menu</em> and <em>Messages</em> view models are <em>Injected</em>. This is an example of dependency injection, correct?</p>
  
  <p>In my case the Menu &amp; Messages view models are created along with the shell.
  But if a new view model</p>
  
  <pre><code>[Export(typeof(UserViewModel))]
  public class UserViewModel : PropertyChangedBase
  {
    private readonly IEventAggregator _events;
  
    [ImportingConstructor]
    public UserViewModel(IEventAggregator eventaggregator)
    {
       _events = eventaggregator;
    }
  }
  </code></pre>
  
  <p>is created when the user presses a button on the MenuView.xaml</p>
  
  <pre><code>&lt;UserControl x:Class="MefCaliburn.MenuView"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
           xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
           xmlns:local="clr-namespace:MefCaliburn"
           xmlns:cal="http://www.caliburnproject.org"
           mc:Ignorable="d" 
           d:DesignHeight="300" d:DesignWidth="300"&gt;
  &lt;Grid&gt;
      &lt;StackPanel Orientation="Horizontal"&gt;
          &lt;Button Content="ONE" cal:Message.Attach="[Event Click] = [Action LaunchUserViewModel()]"&gt;&lt;/Button&gt;
          &lt;Button Content="TWO"&gt;&lt;/Button&gt;
      &lt;/StackPanel&gt;
  &lt;/Grid&gt;
  </code></pre>
  
  <p></p>
  
  <p>This <em>UserViewModel</em> will be publishing events to the <em>MessagesViewModel</em>, I'm going to need the IEventAggregator. Yes, I can just pass it in explicitly to the constructor, but what I'm trying to understand is why MEF won't inject it. </p>
  
  <p>Am I trying to use MEF in a manner it's not intended? Is MEF only meant to be used when the application starts up for those view models that are known to be required?</p>