2

我一直在尝试使用 PRISM 和 MEF 编写 WPF 应用程序,并且能够启动并运行 Shell。我希望能够按需加载模块,所以我需要一个 IModuleManager 在 Shell 中的实例。但是,当我尝试导入它时,应用程序会中断。以下是相关代码:

引导程序:

public class Bootstrapper : MefBootstrapper
{
    protected override DependencyObject CreateShell()
    {
        return this.Container.GetExportedValue<Shell>();
    }

    protected override void InitializeShell()
    {
        base.InitializeShell();

        Application.Current.MainWindow = (Shell)this.Shell;
        Application.Current.MainWindow.Show();
    }

    protected override void ConfigureAggregateCatalog()
    {
        base.ConfigureAggregateCatalog();

        // Add this assembly to export ModuleTracker
        this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));

        DirectoryModuleCatalog moduleCatalog = new DirectoryModuleCatalog();
        moduleCatalog.ModulePath = @".\Modules";
        moduleCatalog.Load();
        foreach (ModuleInfo moduleInfo in moduleCatalog.Modules)
        {
            this.ModuleCatalog.AddModule(moduleInfo);
        }

        DirectoryCatalog catalog = new DirectoryCatalog(@".\Modules");
        this.AggregateCatalog.Catalogs.Add(catalog);

        base.ConfigureAggregateCatalog();
    }

    protected override void ConfigureContainer()
    {
        //Export the Container so that it can be injected if needed.
        this.Container.ComposeExportedValue(Container);

        //Export the Module Catalog so that it can be injected if needed.
        this.Container.ComposeExportedValue(ModuleCatalog);

        base.ConfigureContainer();
    }

    protected override IModuleCatalog CreateModuleCatalog()
    {
        return new ConfigurationModuleCatalog();
    }
}

贝壳:

[Export(typeof(Shell))]
public partial class Shell : Window, IPartImportsSatisfiedNotification
{
    [Import(AllowRecomposition = false)]
    private IModuleManager moduleManager;

    public Shell()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {

    }

    public void OnImportsSatisfied()
    {

    }
}

我得到的例外是:

No exports were found that match the constraint: 
ContractName    Shell
RequiredTypeIdentity    Shell

如果我删除 IModuleManager 的 [Import] 属性,一切正常。我需要做些什么来导出 IModuleManager 吗?

4

2 回答 2

0

通过在 Bootstrapper 中注释以下行来解决此问题:

this.Container.ComposeExportedValue(ModuleCatalog);

不知道为什么它会引起问题,但欢迎对此事有任何见解。

于 2013-03-12T16:25:01.247 回答
0

您必须注意的一件事是同一类型有多个导出。ComposeExportedValue当您使用以及使用 a DirectoryCatalog(可能包含Export相同类型的 an )时,这很容易发生。

Nuget 上有一个很棒的软件包,用于诊断这些问题,称为MEFX

如果你得到这个库,你可以添加以下行来帮助找出发生了什么

var compositionInfo = new CompositionInfo(AggregateCatalog, Container);
CompositionInfoTextFormatter.Write(compositionInfo, Console.Out);

this.Container.ComposeExportedValue(ModuleCatalog);如果您不介意从中发布任何错误,我很想看看当您离开程序时它会打印到“输出”窗口中的内容。

于 2013-03-29T21:43:55.470 回答