如何在基于MEF的模块化应用程序中公开模块功能?

时间:2013-08-27 13:12:05

标签: .net wpf prism mef extensibility

我正在根据Create composite modular UI application in WPF using MEF and PRISM文章的指导构建一个简单的(现在)模块化应用程序。到目前为止,我有一个主窗口,有两个区域,一个Bootstrapper类,以及两个模块项目,ModuleA和ModuleC,它们只导出自己。它们每个都在主窗口的一个区域中放置一个视图(UserControl),例如:

[ModuleExport(typeof(ModuleC))]
public class ModuleC: IModule
{
    public void Initialize()
    {
        IRegionManager regionManager = (IRegionManager)ServiceLocator.Current.GetInstance(typeof(IRegionManager));
        regionManager.Regions["Region2"].Add(new MoneyUserControl());
    }
}

我的愿景是在MainWindow中有一个大的UI区域,它被当前使用的高级应用程序功能使用,并且此功能是导入的模块。虽然这些模块有许多共同之处,并且目前是单片应用程序的一部分,但我基本上只是在提供基本服务的框架(MainWindow),而应用程序的每个功能都作为模块导入。 / p>

我希望活动模块向主窗口提供菜单项(命令)。我可以很容易地“手动”执行此操作,例如一个IModuleWithMenu界面,主窗口查询并集成菜单,或主窗口上的“IMenuHost”界面,并让模块按下菜单命令。

但是,我不禁认为必须有一个更好的方法,因为我已经在使用MEF,并且已经为已加载的模块提供了导出和导入的目录。当然,我可以查询导出并过滤那些命令,并将它们连接到菜单或其他形式的命令调用,但MEF不提供类似已经制作或关闭的东西,我将自己的代码保存到最小,因此存在错误的风险。

另外,另外一个问题:有没有人有关于使用MEF构建复合应用程序的非常好的教程内容的副本或链接(主要是在WPF中,但我可以为WPF调整其他应用程序),因为应该这样做。我完成的文章只是对模块,目录和MEF本身的一个小介绍。我想要真正的,非常技术性的和深入的。购买书籍甚至可能是有序的。

1 个答案:

答案 0 :(得分:2)

虽然我不知道有任何关于创建MEF WPF Prism应用程序的教程,但我目前正在开发许多这些应用程序用于工作,所以我可以提供一些我使用的技巧。

我要说的第一件事是,既然您正在使用MEF,那么您应该使用它。您无需使用ServiceLocator。导入IRegionManager!我真的喜欢MEF而不是Prism中其他IoC容器的另一件事是我通常不会编写IModule实现。您的模块不定义导出,因为它是使用属性处理的。我创建了一个自定义Attribute以将View导出到Region,并创建了一个基础架构IModule,用于在这些区域中注册这些视图。

要向您的应用添加Menu,我认为最好的方法是将Menu导出为单独的View。然后,您的Region只是ContentControl,其名称类似于MenuRegion。如果您有多个注册Menu的视图,则当主视图发生更改时,他们可以在菜单区域上调用IRegionManager.NavigateToView。当然,您可以使用接口(或者您可以使用主视图装饰的属性)来构建基础结构的这一部分,这样各个视图就不必重写相同的代码。

如果您要使用某些全局命令以及导出的菜单命令,您可能需要执行以下两项操作之一:

  • 创建自定义IRegionAdapter以管理如何添加菜单项。在这种情况下,我建议您导出顶级MenuItem个对象。您还可以将单个MenuItem定义为区域。就像FileMenuRegion一样,您可以将MenuItem添加到File菜单。
  • 使用名称导出ICommand,并在处理如何添加命令的特殊ImportMany MainMenu中导出ViewModel。这可能有点复杂,因为您需要找到一种创建菜单层次结构的方法。您可能需要一些可以比ICommand更全面地描述菜单的新界面。