2

首先,我的博客上有一些关于这个问题的背景资料:

我知道描述不是很清楚,所以我会在这里尽可能地总结我正在尝试的内容。该应用程序是一个个人理财程序。本文末尾提供了有关框架本身的更多背景信息。

框架可以处理许多不同类型的插件(例如,帐户、导出、报告等)。但是,我专注于一类特定的插件,即所谓的数据插件,因为正是这类给我带来了问题。我有一类用于帐户的数据插件,一类用于交易等。

我正在进行大规模的重构,这给我留下了以下数据插件架构:

  • 数据插件对象(实现初始化、安装和插件元数据)[实现IDataPlugin<FactoryType>]
  • 数据对象(例如帐户)[实现,例如IAccount]
  • 创建数据对象实例的工厂[实现,例如IAccountFactory]

以前数据对象和插件对象合二为一,但这意味着账户中记录的每笔交易都必须实例化一个新的交易插件,这导致了许多问题。不幸的是,这种重构破坏了我的消息传递。数据对象实现INotifyPropertyChanged了,所以我遇到了一个新问题,我不确定如何解决:插件对象正在向消息代理注册事件,但实际上是数据对象触发了事件。这意味着订阅插件当前必须订阅每个创建的帐户,交易等! 这显然是不可扩展的。

据我目前所知,我有两种可能的解决方案:

  1. 使数据插件对象成为数据对象和消息代理的中间人,可能批量更改通知。我不喜欢这样,因为它给消息传递系统增加了另一层复杂性,我觉得我应该可以不用。
  2. 垃圾当前基于事件的实现并使用其他更易于管理的东西(内存中 WCF?!)。

所以我想我真的在问:

  1. 你将如何解决这个问题?
  2. 您认为我忽略了哪些潜在的解决方案?
  3. 我的方法甚至模糊地走上正轨/明智吗?!:-)

正如您从博客文章的日期中可以看出的那样,这个问题的某些变体已经让我感到很长一段时间了!因此,我们将不胜感激任何和所有的回应。

框架本身的背景如下:

我的插件框架由三个主要组件组成:插件代理、首选项管理器和消息代理。插件代理负责插件的基本工作:发现和创建插件。首选项管理器管理框架和各个插件的用户首选项,例如启用了哪些插件,数据应该保存在哪里等。通过发布/订阅进行通信,消息代理位于中间,收集所有发布的消息类型和管理订阅。发布/订阅当前是通过 .NETINotifyPropertyChanged接口实现的,该接口提供了一个名为PropertyChanged; 消息代理建立一个所有插件实现的列表INotifyPropertyChanged并订阅其他插件此事件。消息传递的目的是让账户和交易插件通知存储插件数据发生了变化,以便保存。

4

3 回答 3

4

哇!大问题!:)

如我错了请纠正我。您现在的基本解决方案是一种观察者模式,其中数据对象(帐户等)通知其状态的变化。您认为问题在于订阅插件必须在每个对象中注册才能处理通知。

这本身不是问题,您可以将事件控制放在域模型中,但我建议您创建一个服务层并在该层中执行此事件通知。这样一来,只有一个对象负责发布通知。

Martin Fowler 在他的博客中有一系列事件模式。看看吧!很好的阅读。

于 2008-09-08T23:25:19.150 回答
3

这是我对您的问题的理解:您有一个插件对象,它可能必须侦听 x 数据对象上的事件——尽管您不想订阅每个数据对象上的事件。我假设几个插件可能想要监听同一个数据对象上的事件。

您可以创建一个会话类型对象。每个插件都会监听会话对象上的事件。数据对象不再引发事件 - 它调用会话对象来引发事件(参数之一必须是引发事件的数据对象)。

That means that your plugins only have to subscribe to one event, but they get the event from all data objects.

On the other hand, if only one plugin will ever listen to a data object at a time, why not just have the data object call the plugin directly?

于 2008-09-09T01:59:07.703 回答
1

现在还为时过早,但您是否考虑过尝试使用MEF而不是自己滚动?

于 2008-09-08T23:39:08.960 回答