c# - 事件聚合器与服务

标签 c# architecture prism eventaggregator

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

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

这样做有好处:

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

和取款:

  • WindowManager 可以完美地独立使用,但现在它需要订阅事件。或者可能更好,其他一些类(class)必须处理这个问题。
  • 扩展它以显示模态对话框有些棘手:如果 VM 触发事件以显示对话框,则发布调用仅在对话框关闭后才返回是非常重要的
  • WindowManager 可作为服务使用,并且位于 CompositionContainer 中,为什么不直接使用它呢?

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

问题:您会使用什么作为指导规则来选择一个或另一个,或者您宁愿只选择一个,还是两者都选择?我必须做出此决定的应用程序设计是否存在特别错误?

最佳答案

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

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

windowManager.ShowDetailsView();

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

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

public void ShowEditView(Action userSavedChanged, Action userCancelled);

然后只需从 View 模型中调用它

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

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

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

关于c# - 事件聚合器与服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8678570/

相关文章:

macos - 在 OS X 上,如何找出共享库的编译架构?

java - 什么时候可以/应该全力使用 ORM 方法?

c# - 如何使用NLog登录到Amazon ElasticSearch?

c# - .NET 控制台在编写某些字符串时播放声音

c# - 垃圾收集和 GCHandle.Alloc

.net - ASP.NET Web 应用程序架构设计建议

c# - 组合框的默认值(设置一次)

c# - View 是否应该间接绑定(bind)到 MVVM 模型中的属性?

arrays - 解析 Unity (Prism) 容器中的数组类型

c# - System.MissingMethodException Message=未找到方法 : DryIoc. 规则 DryIoc.Rules.WithoutFastExpressionCompiler()