WPf、MEF架构设计

WPf、MEF架构设计,wpf,mvvm,architecture,mef,Wpf,Mvvm,Architecture,Mef,在设计可扩展程序的体系结构时,我遇到了一些问题 我正在使用MEF、MMVM Light Toolkit和AvalonDock 第一个问题是如何使用MEF显示从另一个部件导入的某些ViewModel的视图。 为了解决这个问题,我正在导出ResourceDictionary,在这里我为这个程序集中声明的视图定义DataTemplate 词典: <ResourceDictionary ...> <DataTemplate DataType="viewmodels:MyVie

在设计可扩展程序的体系结构时,我遇到了一些问题

我正在使用MEF、MMVM Light Toolkit和AvalonDock

第一个问题是如何使用MEF显示从另一个部件导入的某些
ViewModel
的视图。 为了解决这个问题,我正在导出
ResourceDictionary
,在这里我为这个程序集中声明的视图定义
DataTemplate

词典

<ResourceDictionary 
  ...>
  <DataTemplate DataType="viewmodels:MyViewModel">
    <views:MyViewForViewModel/>
  </DataTemplate>
</ResourceDictionary>

main窗口的构造函数中
我正在导入所有
ResourceDictionary
,并将它们与
MainWidow.ResourceDictionary
合并。 好吗?还可以指定
ResourceDictionary
的“范围”,以将其导入到
MainWindow
,而不是
Application

第二个问题是
ICommands
CommandBindings
。 要填充
菜单
我正在导出'MenuItems',其中我定义了
ICommand
文本
和其他内容,但我不知道如何导出
命令绑定
,我是否应该在无法创建
命令绑定
的情况下使用
RelayCommand

第三个问题是对话。 我发现了一篇很棒的文章,并且很容易将它改编成MEF。但是,例如,我有一个没有任何视图的
IDatabaseService
工作区
,主视图模型,存储
IDatabaseService
的实例,并创建菜单项:
连接到数据库
。使用IDialogService Workspace打开一些导入的
IConnectToDbDialog
所以
Workspace
对此一无所知。对话框关闭时,应将
SqlConnectionString
传递给
IDatabaseService
。 因此,谁必须传递此
SqlConnectionString
IConnectToDbDialog
工作区

第四个问题是如何与
IDatabaseService
正确通信。 例如在某些视图中,我有
按钮
:“在数据库中创建项”。单击按钮时,我应该如何调用
IDatabaseService
方法
CreateItem(ElementType ElementType)
? 问题是,在数据库中有许多按钮创建具有不同
元素类型的
,因此,我认为,使用parametr创建一些
ICommand
是正确的,并且只为该命令创建一个处理程序,该处理程序将调用
IDatabaseService
中的某些方法。但我不知道怎么做。 另一种解决方案是从
ViewModel
IDatabaseService
发送消息以创建项目。
哪种方式更好?

试着回答你的问题

  • 这很好。您可以在XAML或代码隐藏上进行合并,但我更喜欢XAML。您可以将其放在主窗口范围内的MainWindow.Xaml或应用程序范围内的App.Xaml上

  • 我以前没有导出视图。在我看来,如果您将CommandBindings放在菜单下,那么如果事件处理程序在导入环境的范围内,则它在何时导出然后导入并不重要

  • 视情况而定。理论上,您可以将服务调用放在所有者的视图模型或dialog的视图模型中。例如,如果您的对话框有一个“创建/提交”按钮,并且您希望该对话框在提交成功之前保持活动状态,那么请将其放入对话框的视图模型中,以便在处理异常时保持打开状态。如果不需要对话框保持打开状态,则可以在对话框关闭后将逻辑放入所有者的视图模型中

  • 指挥更好。考虑到视图模型从IoC容器获取IDatabaseService对象,您可能有一个ICommand属性接受ElementType参数,或者参数器可以映射到ElementType。在execute方法中,调用CreateItem直接或从映射器传递参数。在XAML上,将type放入命令绑定中。这有意义吗


  • 希望能有所帮助。

    谢谢。3和4的答案很清楚,但我有一些关于1和2的问题,可能是我的错。1.我也更喜欢XAML,但在我的任务中,我只能访问主程序集源代码和通用接口,无法访问视图、菜单或其他块源代码,因此除了我的解决方案之外,我看不到任何其他解决方案。我不知道怎么做。我只能访问
    IMenu
    IMenuItem
    接口和
    MenuItem
    类。在某些程序集中,我在
    ResourceDictionary
    中导出
    类菜单:IMenu
    DataTemplate
    ,以在shell中显示菜单。为了添加一些
    IMenuItem
    我正在导出
    类MenuItem:IMenuItem
    或者在从IoC获取的
    IMenu
    中调用方法
    AddMenuItem(IMenuItem)
    ,因此我无法在
    菜单下定义
    命令绑定。我只能在代码中这样做,但这是有问题的,但也是可能的。在共享程序集中,公共类工作空间命令{public static RoutedUICommand ConnectToDB{get{return ConnectToDB;}}}static readonly RoutedUICommand ConnectToDB=new RoutedUICommand(“连接到数据库”,“连接到数据库”,typeof(工作空间命令));}在
    main窗口
    或其他地方,我必须创建
    CommandBinding
    来处理它。我没有看到命令绑定与您的菜单有任何关系。您的RoutedCommand是在共享程序集上定义的,而您的命令绑定是在XAML上定义的。请您解释一下,我不明白。