2

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

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

这有以下好处:

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

和提款:

  • WindowManager 可以完全独立使用,但现在它需要订阅事件。或者可能更好,其他一些班级必须处理这个问题。
  • 将其扩展为显示模式对话框有些棘手:如果 VM 触发事件以显示对话框,则 Publish 调用仅在对话框关闭后返回至关重要
  • WindowManager 可作为服务使用,它位于 CompositionContainer 中,为什么不直接使用它呢?

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

问题:你会使用什么作为指导规则来选择一个或另一个,或者你宁愿总是只选择一个,还是两者都选?我的应用程序设计中是否有什么特别错误的地方需要我做出这个决定?

4

1 回答 1

3

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

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

windowManager.ShowDetailsView();

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

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

public void ShowEditView(Action userSavedChanged, Action userCancelled);

然后只需从视图模型中调用它

windowManager.ShowEditView(this.SaveChanges, this.CancelChanges);

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

希望这一切都有意义。毕竟是星期五:)

于 2011-12-30T11:32:22.070 回答