在外部程序集中查找ViewModel的View

时间:2014-01-15 14:00:42

标签: wpf mvvm mef caliburn.micro

我在我的应用程序中使用MEF来加载一些简单的插件。每个插件都包含一个ViewModel和一个相应的View。

我能够成功创建此类插件的ViewModel实例,但是Caliburn.Micro说它无法找到它的视图。插件中的ViewModel称为 SimpleValueDisplayViewModel ,视图 SimpleValueDisplayView ,名称空间相同。

我的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);            
    }
}

我是否需要告知Caliburn.Micro关于MEF在“插件”目录中找到的程序集?

编辑:我尝试重写SelectAssemblies并将“插件”目录中的所有程序集添加到AssemblySource.Instance。然而,然后我得到MEF找到程序集两次的问题,这反过来在我实例化ViewModel时会产生问题。

1 个答案:

答案 0 :(得分:6)

好的,在阅读并理解了这一点后,我开始工作了。我从AggregateCatalog中删除了DirectoryCatalog,并在创建AggregateCatalog之前将Plugins-folder中的.dll添加到AssemblySource.Instance。

这种方式适用于Caliburn.Micro和MEF。

新的引导程序代码:

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);            
}