如何设计棱镜EventAggregator?
发布-订阅事件的模式是 出版商不应该知道或关心 那里有订阅者, 它也不应该关心什么 订户如果在那里就会这样做(来自 布莱恩·诺伊斯的 博客)
在 Prism 中使用 EventAggregator 的最佳实践是什么?目前我有几个松散耦合且独立工作的模块。这些模块使用 EventAggregator 与其他模块进行通信。随着应用程序的增长,我对如何记录我的代码感到困惑。可能有许多模块发布事件,还有许多其他模块订阅它,正如布莱恩所说,他们都不知道其他模块到底做了什么。创建新模块时,如何确保它们订阅某些 XYZ 事件而不破坏松散耦合的结构?
如何使用 EventAggregator 直观地表示模块(某种图表)?
Pattern of pub-sub events is that the
publisher should not know or care if
there are any subscribers out there,
nor should it care what the
subscribers do if they are there (from
Brian Noyes'
blog)
What are the best practices to using EventAggregator in Prism? Currently I have few modules which are loosely coupled and work independently. These modules use EventAggregator to communicate to other modules. As the application grows I'm confused on how to document my code. There could be many modules publishing Events and many others subscribing to it as Brian puts neither of them knows what other does exactly. When creating a new module how do I make sure they are subscribed to some XYZ event without breaking the loosely coupled structure?
How do I represent a module using EventAggregator visually (some kind of diagrams)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的帖子中有很多问题可以回答“这取决于您的应用程序”,但我会尝试回答其中一些问题。
我在 EventAggregator 中最常看到的一件事是滥用。许多人使用 EventAggregator 的方式使发布者和订阅者相互依赖。这给我带来了第一点建议:
永远不要假设某个事件有任何订阅者。
EventAggregator 对于发布其他视图可能感兴趣的事件非常有用。例如,在我们的应用程序中,我们允许用户更改某人的名字。该名称可能会显示在应用程序中已打开的其他视图上(我们有一个选项卡式 UI)。我们的用例是我们希望在名称更改时更新这些 UI,因此我们发布了一个“UserDataChanged”事件,以便打开的视图可以适当地订阅和刷新其数据,但如果没有打开的视图对此数据感兴趣,没有通知订阅者。
在适当的情况下优先使用 .NET 事件而不是 EventAggregator 事件
我经常看到的另一个错误是使用 EventAggregator 实现的业务流程,其中数据被发送到中央方,然后该方进行回复,所有这些都使用 EventAggregator。这会导致一些您可能希望避免的副作用。
我经常看到的一个变化是从父视图到子视图的通信,反之亦然。类似于“TreeItemChecked”或“ListViewItemSelected”。这是使用传统 .NET 事件的情况,但作者认为,如果他们有一把锤子(EventAggregator),那么所有东西(事件)看起来都像钉子。
您询问对 EventAggregator 进行建模,我会这样说:EventAggregator 的特殊之处在于它允许解耦并且不会创建对事件的强引用(避免内存泄漏等)。除此之外,它实际上只是观察者模式<的一个非常微小的变化/强>。然而,您对观察者进行建模就是在您尝试创建的任何类型的图表中对 EventAggregator 进行建模的方式。
至于您关于确保某个模块或另一个模块订阅了事件的问题:您没有。如果您需要确保有订阅者,则不应使用 EventAggregator。在这些情况下,我建议在您的应用程序中运行一个服务,模块可以从您的容器中获取并使用该服务或其他类似的东西。
关于模块需要记住的一点是,您应该能够完全删除一个模块,并且应用程序的其余部分可以正常运行。如果情况并非如此,则您要么具有模块依赖性(最好避免,但可以理解),或者应该将依赖模块合并为一个。
You have a lot of questions in your post that can be answered "it depends on your application," but I'll try to answer some of them.
One thing that I see most often with EventAggregator is abuse. Many people use EventAggregator in a way that makes both the publisher and subscriber dependent on each other. This brings me to my first bit of advise:
Never assume there are any subscibers to an event.
EventAggregator is useful for publishing events other views might be interested in. For example, in our application we allow a user to change someone's name. This name might be displayed on other views already open in the application (we have a tabbed UI). Our use case was we wanted to have those UIs update when the name was changed, so we published a "UserDataChanged" event so that open views could subscribe and refresh their data appropriately, but if no views that were open were interested in this data, no subscribers were notified.
Favor .NET Events over EventAggregator events where appropriate
Another mistake I see frequently is a business process that is implemented using EventAggregator where data is sent to a central party and then that party replies, all using EventAggregator. This is leads to some side-effects you'd likely want to avoid.
A variation on that I see a lot is communication from a parent view to a sub-view, or vice-versa. Something like "TreeItemChecked" or "ListViewItemSelected". This is a situation where traditional .NET Events would be used, but an author decided that if they have a hammer (EventAggregator), everything (Events) looks like a nail.
You asked about modeling the EventAggregator and I would say this: the EventAggregator is only special in that it allows for decoupling and doesn't create strong references to events (avoiding memory leaks, etc). Other than that, it's really just a very slight variation of the Observer Pattern. However you are modeling Observers is how you would model the EventAggregator in whatever type of diagram you are trying to create.
As to your question about making sure some module or another is subscribed to an event: you don't. If you need to ensure there are subscribers, you should not use the EventAggregator. In these cases I would recommend a service running in your application that modules can grab from your container and use or other similar thing.
The thing to keep in mind about your modules is that you should be able to completely remove one and the rest of your application functions normally. If this is not the case, you either have a module dependency (best to be avoided, but understandable), or dependent modules should be combined into one.