今天在网上闲逛,偶然发现一个老外的开源组件,里面实现了微软SCSF框架中的EventBroker模块的功能,它的使用和SCSF几乎一样,熟悉SCSF的人几乎一下就能上手,只是这个类库不再像SCSF一样,只能在框架中使用,它不依赖于SCSF,可以用在WinForm,WPF中,是一个独立的组件。
原本应该在"Code Project"上可以下载的,上面只有它的介绍,下载链接好像有问题
http://www.codeproject.com/Articles/30066/EventBroker-a-notification-component-for-synchrono
我在百度上找了很久,终于找到一个可以下载的地方,这里是它的源码。
http://sourceforge.net/projects/bbvcommon/
我之所以青睐这个库,是因为它用C#的Attribute解耦了事件注册时由"+="带来的调用方与接收方的依赖(当然解耦的方式有很多,但我觉得这个方式最优雅)
下面就是一个事件发布类,它采用了Attribute来标记,其中的"topic://EventBrokerSample/SimpleEvent"为事件的Uri,是他的唯一标示。
public class Publisher
{
[EventPublication("topic://EventBrokerSample/SimpleEvent")]
public event EventHandler SimpleEvent;
///<summary>Fires the SimpleEvent</summary>
public void CallSimpleEvent()
{
SimpleEvent(this, EventArgs.Empty);
}
}
下面是事件的订阅部分,同样是用Attribute来标记,采用同样的Uri来标示为上面事件的接收
public class Subscriber
{
[EventSubscription(
"topic://EventBrokerSample/SimpleEvent",
typeof(Handlers.Publisher))]
public void SimpleEvent(object sender, EventArgs e)
{
// do something useful or at least funny
}
}
最后,包含事件订阅的对象需要EventBroker来注册,这个相当与"+=",只是它可以完全不关注事件的发布者是谁(这和SCSF的方式一模一样),它使用的是反射Attribute元数据的方式,然后调用DynamicInvoke方法调用委托
下面是我使用该组件的一个例子
窗体上下,各自放了一个UserControl,首先他们加载的时候,接受了窗体Form1触发的事件,然后点击UserControl1的按钮改变UserControl2的文本框文本,反之UserControl2亦然,我用单例模式把EventBroker对象管理了起来,不然使用起来太不方便了
- public class EventBrokerCreator
- {
- private static EventBroker _instance = null;
- private EventBrokerCreator()
- {}
- public static EventBroker GetEventBroker()
- {
- return _instance ?? (_instance = new EventBroker());
- }
- }
- public partial class UserControl1 : UserControl
- {
- public UserControl1()
- {
- InitializeComponent();
- }
- [EventPublication(EventTopics.UserCtrol1)]
- public event EventHandler UserCtrol1Event;
- private void button1_Click(object sender, EventArgs e)
- {
- if (UserCtrol1Event != null)
- UserCtrol1Event(this, EventArgs.Empty);
- }
- [EventSubscription(EventTopics.UserCtrol2, typeof(Publisher))]
- public void UserCtrol1Send(object sender, EventArgs e)
- {
- textBox1.Text = "UserControl2 Send";
- }
- [EventSubscription(EventTopics.Form1, typeof(Publisher))]
- public void Form11Send(object sender, EventArgs e)
- {
- textBox1.Text = "Form1 Send";
- }
- }
- public partial class UserControl2 : UserControl
- {
- public UserControl2()
- {
- InitializeComponent();
- }
- [EventPublication(EventTopics.UserCtrol2)]
- public event EventHandler UserCtrol2Event;
- private void button1_Click(object sender, EventArgs e)
- {
- if (UserCtrol2Event != null)
- UserCtrol2Event(this, EventArgs.Empty);
- }
- [EventSubscription(EventTopics.UserCtrol1, typeof(Publisher))]
- public void UserCtrol1Send(object sender, EventArgs e)
- {
- textBox1.Text = "UserControl1 Send";
- }
- [EventSubscription(EventTopics.Form1, typeof(Publisher))]
- public void Form11Send(object sender, EventArgs e)
- {
- textBox1.Text = "Form1 Send";
- }
- }
在Form1中发布一个事件,两个用户控件来订阅
- public partial class Form1 : Form
- {
- public Form1()
- {
- //为了方便说明,用户控件的实例化部分从Designer.cs中移到这里
- this.userControl1 = new Sample.UserControl1();
- this.userControl2 = new Sample.UserControl2();
- //注册事件订阅对象
- var eventBroker = EventBrokerCreator.GetEventBroker();
- eventBroker.Register(userControl1);
- eventBroker.Register(userControl2);
- InitializeComponent();
- }
- [EventPublication(EventTopics.Form1)]
- public event EventHandler Form1Event;
- private void Form1_Load(object sender, EventArgs e)
- {
- if (Form1Event != null)
- Form1Event(this, EventArgs.Empty);
- }
- }
- static void Main()
- {
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- //由于是单例模式,所有的EventBroker对象都是同一个
- var eventBroker = EventBrokerCreator.GetEventBroker();
- var form1 = new Form1();
- eventBroker.Register(form1);
- Application.Run(form1);
- }