Search code examples
wpfmefcaliburn.micro

Caliburn.Micro and MEF on wpf


I am just learning WPF and Caliburn.Micro. I am following the code that presented here: http://caliburnmicro.codeplex.com/wikipage?title=Customizing%20The%20Bootstrapper&referringTitle=Documentation

Apparently this code is for Silverlight but my project is a WPF and for this reason I am getting error that CompositionHost is not defined.

The document stated that I need to initialize the container directly in wpf, but there is no document to show how. How can I initialize the container directly?

Edit 1 The boot strapper is like this in documentation:

     container = CompositionHost.Initialize(
        new AggregateCatalog(
            AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()
            )
        );

    var batch = new CompositionBatch();

    batch.AddExportedValue<IWindowManager>(new WindowManager());
    batch.AddExportedValue<IEventAggregator>(new EventAggregator());
    batch.AddExportedValue(container);

    container.Compose(batch);

and I converted it to :

    var catalog =
            new AggregateCatalog(
                AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>());

        this.container = new CompositionContainer(catalog);
        var batch = new CompositionBatch();

        batch.AddExportedValue<IWindowManager>(new WindowManager());
        batch.AddExportedValue<IEventAggregator>(new EventAggregator());
        batch.AddExportedValue(this.container);

        this.container.Compose(batch);

But when I run application, I am getting error that MEF can not find implementation for IShell

     Could not locate any instances of contract IShell.

I belive my initialization of MEF is not correct. Can you please help me fix it?


Solution

  • In WPF you need to use an explicit CompositionContainer constructor. In my WPF and Silverlight shared bootstrapper I have used the following #if-#else directive:

    #if SILVERLIGHT
        container = CompositionHost.Initialize(catalog);
    #else
        container = new CompositionContainer(catalog); ;
    #endif
    

    EDIT

    The bootstrapper will identify a component that implements the IShell interface (provided your bootstrapper is extending the Bootstrapper<IShell> base class), so you need to implement a class decorated with MEF export of IShell.

    Typically this would be your ShellViewModel and the declaration would look like this:

    [Export(typeof(IShell))]
    public class ShellViewModel : PropertyChangedBase, IShell
    {
       ...
    }
    

    You can read much more about bootstrapper setup and customization here.