在企业级应用软件开发中,事件聚合模式(Event Aggregator Pattern)是一种处理事件的高效方式。它允许应用程序中的对象以松耦合的方式进行通信。本文将介绍事件聚合模式的基本概念、实现方式以及在.NET环境中的具体应用示例。
在软件应用中,事件通常用来表示对象状态、组件状态或应用状态等重要变化的发生。从小型到大型的软件应用都会使用事件来指示变化,并作为内部和外部通信的基础。事件允许两个或多个对象通过发布者(Publisher)指定何时发生事件,然后允许多个订阅者(Subscriber)订阅该事件,实现通信。发布者对象不需要直接引用订阅者对象,也不需要知道它们的存在,只要事件相关的接口不发生变化,发布者的变化就不会影响订阅者。
随着软件应用规模的扩大,传统的事件处理方式会面临一些挑战:
事件聚合模式通过提供一个中央位置来发布和订阅事件,即事件聚合器(Event Aggregator),来克服传统事件处理的局限性。事件聚合器负责注册、注销和调用事件,松耦合发布者和订阅者。所有事件的发布者和订阅者只知道事件聚合器。
事件聚合模式的主要目的是:
实现事件聚合模式有多种方式,具体实现可能会根据所使用的软件开发环境和语言基础设施而有所不同。以下是一个使用.NET 4.0框架和C#语言实现的示例程序。
在示例程序中,有三个与项目对象相关的事件及其参数:
public class ItemCreated {
public Item Item { get; set; }
}
public class ItemSaved {
public Item Item { get; set; }
}
public class ItemSelected {
public Item Item { get; set; }
}
为了允许事件被订阅和发布,需要在应用程序中创建一个事件聚合器的全局实例:
this.ea = new EventAggregator.EventAggregator();
这个全局实例必须对应用程序中的所有发布者和订阅者可用。
订阅者需要实现ISubscriber<TEventType>接口,其中TEventType是它感兴趣的事件类型。接口定义如下:
public interface ISubscriber<TEventType> {
void OnEventHandler(TEventType e);
}
在示例程序中,ItemView用户控件订阅了所有三个事件:
public partial class ItemView : UserControl, ISubscriber<ItemSaved>, ISubscriber<ItemSelected>, ISubscriber<ItemCreated> {
public ItemView(IEventAggregator ea) {
InitializeComponent();
// 订阅所有事件。
ea.SubscribeEvent(this);
}
// ... 省略其他代码 ...
}
发布者需要调用IEventAggregator.PublishEvent<TEventType>(TEventType eventToPublish)方法,并传递在步骤1中确定的事件类型实例。
this.EventAggregator.PublishEvent(new ItemSaved() { Item = savedItem });
事件聚合器实现了IEventAggregator接口,接口定义如下:
public interface IEventAggregator {
void PublishEvent<TEventType>(TEventType eventToPublish);
void SubscribeEvent(Object subscriber);
}
事件聚合器维护一个内部字典,用于存储每种事件类型及其调用列表作为WeakReference。当Subscriber调用SubscribeEvent(Object subscriber)方法时,它使用反射确定该实例支持的所有ISubscriber<TEventType>类型,并将其存储在字典中。该方法通常在订阅者的构造函数逻辑中只调用一次。
当Publisher调用PublishEvent<TEventType>(TEventType eventToPublish)方法时,它会获取订阅了TEventType的实例的调用列表,并在它们仍然在应用程序中活跃时调用它们,否则将它们从调用列表中移除。