我一直在尝试使用PRISM和MEF编写WPF应用程序,并且我已经能够启动并运行Shell。我希望能够按需加载模块,因此我需要在Shell中使用IModuleManager的实例。但是,当我尝试导入它时,应用程序会中断。以下是相关代码:
引导程序:
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需要做些什么吗?
答案 0 :(得分:0)
通过在Bootstrapper中注释以下行来解决此问题:
this.Container.ComposeExportedValue(ModuleCatalog);
不确定为什么会导致问题,但欢迎任何有关此问题的见解。
答案 1 :(得分:0)
您必须注意的一件事是同一类型的多个导出。当您使用ComposeExportedValue
以及使用DirectoryCatalog
(可能包含相同类型的Export
)时,很容易发生这种情况。
Nuget有一个很棒的软件包来诊断这些问题MEFX
如果你有这个库,你可以添加以下行来帮助找出正在发生的事情
var compositionInfo = new CompositionInfo(AggregateCatalog, Container);
CompositionInfoTextFormatter.Write(compositionInfo, Console.Out);
如果您不介意发布任何错误,我会很高兴看到当您在程序中保留this.Container.ComposeExportedValue(ModuleCatalog);
时打印到“输出”窗口的内容。