eventaggregator与服务

时间:2011-12-30 10:38:01

标签: c# architecture prism eventaggregator

当使用Prism和MEF / Unity开发相当大的应用程序时,我总是会在使用事件,服务或两者之间做出选择。我无法决定最有用的东西。也许我的架构有问题(因为这个决定不应该在第一时间做出),但我看不出是什么。

这是一个典型的例子:我的应用程序有一个主窗口和很多从属窗口,这些窗口是按模块或用户操作按需创建的。应用程序决定从属窗口的chrome的外观和行为,记住窗口放置等,同时在模块中的某个位置创建内容本身。还有许多用户操作导致隐藏/显示/带到窗口前面。为了实现这一切,我目前有一个监听CreateWindow / SetWindowState / ..事件的WindowManager服务。

这有好处:

  • 使用它的类只知道IEventAggregator(它们大部分时间已经用于其他事件)和WindowManager消耗的事件,而不是WindowManager本身
  • 像ViewModels这样的类不直接处理windows。相反,他们通过他们的标题或id以及封装了所需内容的小事件类来引用它们。
  • 不需要单独的IWindowManager接口只是为了在测试中模拟它

提款:

  • WindowManager可以完全独立使用,但现在它需要订阅事件。或者可能更好,其他一些班级必须要照顾它。
  • 扩展它以显示模态对话框有点棘手:如果VM触发事件以显示对话框,那么发布调用仅在对话框关闭后返回是非常重要的
  • WindowManager作为服务提供,它在CompositionContainer中,为什么不这样使用呢?

直接使用该服务只会改变福利/提款,并且似乎没有明显的赢家。

问题:你会用什么作为指导规则来挑选一个或另一个,或者你宁愿总是选择一个或两个?我的应用程序设计中有什么特别错误,我必须做出这个决定吗?

1 个答案:

答案 0 :(得分:3)

事件和服务用于不同的事情。您不必在它们之间进行选择,您可以将它们用于不同的目的。您通常会使用事件来通知侦听器已发生的事情。示例:用户更改应用程序设置中的字体大小。您将向所有侦听器(例如视图模型)发送事件,以便更新视图。通常事件是一种你没有得到响应的东西(尽管你可以附加例如事件监听器会调用的回调函数/动作)。

如果您的viewmodel需要打开新窗口怎么办?通常,viewmodel不应该关心这个新窗口是如何打开的,或者它是否是模态的。在这种情况下,使用服务很容易:

windowManager.ShowDetailsView();

WindowManager(您通过IWindowManager界面使用)负责显示详细信息视图。也许它是一个模态视图或者可能有某种幻灯片动画。关键是使用IWindowManager的视图模型不关心。

在某些情况下,如果用户点击“确定”或“取消”,您可能需要接收通知。你仍然可以通过这样的方法使用IWindowManager:

public void ShowEditView(Action userSavedChanged, Action userCancelled);

然后从viewmodel

中调用它
windowManager.ShowEditView(this.SaveChanges, this.CancelChanges);

// in your viewmodel you have the SaveChanges and CancelChanges methods
private void SaveChanges()
{
   // save the changes.
}

希望这一切都有道理。毕竟它是周五:)