两次导入类型会导致MEF失败

时间:2014-08-20 18:41:58

标签: c# mef

我正在尝试用MEF编写一个小模块系统,所以我有一个像这样的基本模块:

public abstract class Module : IModule
{
    [Import]
    private IShell _shell;

    protected IShell Shell
    {
        get { return _shell; }
    }
}

还有一些模块如下:

[Export(typeof(IModule))]
public class TodoListModule : Module
{

}

如您所见,基本模块依赖于IShell。我有一个实现,像这样:

[Export(typeof(IShell))]
public class ShellViewModel : IShell
{
    [ImportMany]
    private IEnumerable<IModule> _modules;

    .... and later...

    private void InitializeModules()
    {
        foreach (var module in _modules)
        {
            // init modules.
        }
    }
}

所以shell负责加载模块。

问题是当我有多个模块实现时,我得到了这个例外:

GetExportedValue cannot be called before prerequisite import '...ShellViewModel..ctor' has been set.

因此,原因是我们有2个实现通过基类获得IShell。为什么会这样?

这是我的容器配置:

        // Add all assemblies to AssemblySource (using a temporary DirectoryCatalog).
        var directoryCatalog = new DirectoryCatalog(@"./");
        AssemblySource.Instance.AddRange(
            directoryCatalog.Parts
                .Select(part => ReflectionModelServices.GetPartType(part).Value.Assembly)
                .Where(assembly => !AssemblySource.Instance.Contains(assembly)));

        // Prioritise the executable assembly. This allows the client project to override exports, including IShell.
        // The client project can override SelectAssemblies to choose which assemblies are prioritised.
        var priorityAssemblies = SelectAssemblies().ToList();
        var priorityCatalog = new AggregateCatalog(priorityAssemblies.Select(x => new AssemblyCatalog(x)));
        var priorityProvider = new CatalogExportProvider(priorityCatalog);

        // Now get all other assemblies (excluding the priority assemblies).
        var mainCatalog = new AggregateCatalog(
            AssemblySource.Instance
                .Where(assembly => !priorityAssemblies.Contains(assembly))
                .Select(x => new AssemblyCatalog(x)));
        var mainProvider = new CatalogExportProvider(mainCatalog);

        container = new CompositionContainer(priorityProvider, mainProvider);
        priorityProvider.SourceProvider = container;
        mainProvider.SourceProvider = container;

        var batch = new CompositionBatch();

        BindServices(batch);
        batch.AddExportedValue(mainCatalog);

        container.Compose(batch);

当任何其他类导入IShell

时,也会发生这种情况

0 个答案:

没有答案