消息在插件框架中传递
首先,我的博客提供了一些有关此问题的背景知识:
- http://www.codebork.com/coding/2008/06/25/message-passing-a-plug-framework.html
- http://www.codebork.com/coding/2008/07/31/message-passing-2.html
我知道描述不是很清楚,所以我将尽力在这里总结我正在尝试的内容。该应用程序是个人理财程序。这篇文章的末尾提供了有关框架本身的更多背景信息。
框架可以处理许多不同类型的插件(例如,帐户,导出,报告等)。但是,我专注于一类特定的插件,即所谓的数据插件,因为正是此类导致了我的问题。我有一类用于帐户的数据插件,一类用于交易等。
我正在进行大量重构,这使我有了以下用于数据插件的体系结构:
- 数据插件对象(实现初始化,安装和插件元数据)[实现
IDataPlugin <FactoryType>
] - 数据对象(例如帐户)[实现,例如
IAccount
] - 用于创建数据对象实例的工厂[实现,例如
IAccountFactory
]
以前,数据对象和插件对象合并为一个对象,但这意味着必须为帐户中记录的每个事务实例化一个新的事务插件,这会导致许多问题。不幸的是,这种重构破坏了我的信息传递。数据对象实现了INotifyPropertyChanged
,所以我遇到了一个新问题,一个我不确定如何解决的问题:插件对象正在向消息代理注册事件,但是它是数据对象实际触发事件。这意味着订阅插件当前必须订阅每个创建的帐户,交易等!这显然是不可扩展的。
据我目前所知,我有两种可能的解决方案:
- 使数据插件对象成为数据对象和消息代理之间的中间对象,可能是批量更改通知。我不喜欢这样,因为它给消息传递系统增加了另一层复杂性,我认为我应该可以做到。
- 废弃当前基于事件的实现,并使用其他更易于管理的东西(内存中的WCF ?!)。
所以我想我真的是在问:
- 我们将如何解决这个问题?
- 我们认为我忽略了哪些潜在的解决方案?
- 我的方法是否还算是正确/合理? :-)
从博客文章的日期中可以看出,这个问题的某些变种已经使我很久了!这样,将非常感谢任何和所有答复。
框架本身的背景如下:
My plug-in framework consists of three main components: a plug-in broker, a preferences manager and a message broker. The plug-in broker does the bread-and-butter plug-in stuff: discovering and creating plug-ins. The preferences manager manages user preferences for the framework and individual plug-ins, such as which plug-ins are enabled, where data should be saved, etc. Communication is via publish/subscribe, with the message broker sitting in the middle, gathering all published message types and managing subscriptions. The publish/subscribe is currently implemented via the .NET INotifyPropertyChanged interface, which provides one event called PropertyChanged; the message broker builds a list of all plug-ins implementing INotifyPropertyChanged and subscribes other plug-ins this event. The purpose of the message passing is to allow the account and transaction plug-ins to notify the storage plug-ins that data has changed so that it may be saved.
解决方案
回答
哇!大问题! :)
如我错了请纠正我。现在,基本解决方案是一种观察者模式,其中数据对象(帐户等)通知其状态更改。我们认为问题在于订阅插件必须在每个对象中注册才能处理通知。
这本身不是问题,我们可以将事件控件放入域模型中,但是我建议我们创建一个服务层并在此层中进行此事件通知。这样,只有一个对象将负责发布通知。
马丁·福勒(Martin Fowler)的博客中提供了一系列事件模式。一探究竟!很好的阅读。
回答
还很早,但是我们是否考虑过尝试使用MEF而不是自己动手?
回答
这是我对问题的理解:我们有一个插件对象,该插件对象可能不得不侦听我们不想订阅每个数据对象上的事件的x个数据对象上的事件。我假设有几个插件可能希望侦听同一数据对象上的事件。
我们可以创建一个会话类型对象。每个插件都监听会话对象上的事件。数据对象不再引发事件,而是调用会话对象引发事件(参数之一必须是引发事件的数据对象)。
这意味着插件只需要订阅一个事件,但是它们可以从所有数据对象中获取事件。
另一方面,如果一次只有一个插件会监听一个数据对象,为什么不让数据对象直接调用该插件呢?