Question

I am using MEF in my application to load some simple plugins. Each plugin consists of a ViewModel and a corresponding View.

I am able to successfully create instances of the ViewModel of such a plugin, however Caliburn.Micro says it is unable to locate a view for it. The ViewModel in the plugin is called SimpleValueDisplayViewModel and the view SimpleValueDisplayView, with the same name space.

Relevant code in my Bootstrapper:

public class MefBootstrapper : Bootstrapper<ShellViewModel>
{   
    protected override void Configure()
    {
        string pluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
        if (!Directory.Exists(pluginPath))
            Directory.CreateDirectory(pluginPath);

        var catalog = new AggregateCatalog(
            AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()
            .Concat(new ComposablePartCatalog[] { new DirectoryCatalog("Plugins")})
            );

        _container = new CompositionContainer(catalog);
        var batch = new CompositionBatch();

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

        _container.Compose(batch);            
    }
}

Do I somehow need to inform Caliburn.Micro about the assemblies that MEF finds in the "Plugins"-directory?

Edit: I tried overriding SelectAssemblies and adding all the assemblies in the "Plugins"-directory to AssemblySource.Instance. However, I then get then get a problem with MEF finding the assembly twice, which in turn creates problem when I am to instantiate the ViewModel.

Was it helpful?

Solution

OK, after reading and understanding this a bit better, I got it working. I removed the DirectoryCatalog from the AggregateCatalog, and added the .dlls in the Plugins-folder to AssemblySource.Instance before creating the AggregateCatalog.

This way it worked for both Caliburn.Micro and MEF.

New bootstrapper code:

protected override void Configure()
{
    string pluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
    if (!Directory.Exists(pluginPath))
        Directory.CreateDirectory(pluginPath);

    var fi = new DirectoryInfo(pluginPath).GetFiles("*.dll");
    AssemblySource.Instance.AddRange(fi.Select(fileInfo => Assembly.LoadFrom(fileInfo.FullName)));

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

    _container = new CompositionContainer(catalog);

    var batch = new CompositionBatch();
    batch.AddExportedValue<IWindowManager>(new WindowManager());
    batch.AddExportedValue<IEventAggregator>(new EventAggregator());
    batch.AddExportedValue(_container);

    _container.Compose(batch);            
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top