类似SCSF中EventBroker解耦事件调用方和接受方,打破"+="带来的耦合

今天在网上闲逛,偶然发现一个老外的开源组件,里面实现了微软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对象管理了起来,不然使用起来太不方便了

  1. public class EventBrokerCreator  
  2. {  
  3.     private static EventBroker _instance = null;  
  4.     private EventBrokerCreator()  
  5.     {}  
  6.   
  7.     public static EventBroker GetEventBroker()  
  8.     {  
  9.         return _instance ?? (_instance = new EventBroker());  
  10.     }  
  11. }  
下面是两个用户控件,他们各自定义了事件的发布和订阅
  1. public partial class UserControl1 : UserControl  
  2. {  
  3.     public UserControl1()  
  4.     {  
  5.         InitializeComponent();  
  6.     }  
  7.   
  8.     [EventPublication(EventTopics.UserCtrol1)]  
  9.     public event EventHandler UserCtrol1Event;  
  10.   
  11.     private void button1_Click(object sender, EventArgs e)  
  12.     {  
  13.         if (UserCtrol1Event != null)  
  14.             UserCtrol1Event(this, EventArgs.Empty);  
  15.     }  
  16.   
  17.     [EventSubscription(EventTopics.UserCtrol2, typeof(Publisher))]  
  18.     public void UserCtrol1Send(object sender, EventArgs e)  
  19.     {  
  20.         textBox1.Text = "UserControl2 Send";  
  21.     }  
  22.   
  23.     [EventSubscription(EventTopics.Form1, typeof(Publisher))]  
  24.     public void Form11Send(object sender, EventArgs e)  
  25.     {  
  26.         textBox1.Text = "Form1 Send";  
  27.     }  
  28. }  

  1. public partial class UserControl2 : UserControl  
  2. {  
  3.     public UserControl2()  
  4.     {  
  5.         InitializeComponent();  
  6.     }  
  7.   
  8.     [EventPublication(EventTopics.UserCtrol2)]  
  9.     public event EventHandler UserCtrol2Event;  
  10.   
  11.     private void button1_Click(object sender, EventArgs e)  
  12.     {  
  13.         if (UserCtrol2Event != null)  
  14.             UserCtrol2Event(this, EventArgs.Empty);  
  15.     }  
  16.   
  17.     [EventSubscription(EventTopics.UserCtrol1, typeof(Publisher))]  
  18.     public void UserCtrol1Send(object sender, EventArgs e)  
  19.     {  
  20.         textBox1.Text = "UserControl1 Send";  
  21.     }  
  22.   
  23.     [EventSubscription(EventTopics.Form1, typeof(Publisher))]  
  24.     public void Form11Send(object sender, EventArgs e)  
  25.     {  
  26.         textBox1.Text = "Form1 Send";  
  27.     }  
  28. }  

在Form1中发布一个事件,两个用户控件来订阅
  1. public partial class Form1 : Form  
  2. {  
  3.     public Form1()  
  4.     {  
  5.         //为了方便说明,用户控件的实例化部分从Designer.cs中移到这里  
  6.         this.userControl1 = new Sample.UserControl1();  
  7.         this.userControl2 = new Sample.UserControl2();  
  8.         //注册事件订阅对象  
  9.         var eventBroker = EventBrokerCreator.GetEventBroker();  
  10.         eventBroker.Register(userControl1);  
  11.         eventBroker.Register(userControl2);  
  12.         InitializeComponent();  
  13.     }  
  14.   
  15.     [EventPublication(EventTopics.Form1)]  
  16.     public event EventHandler Form1Event;  
  17.   
  18.     private void Form1_Load(object sender, EventArgs e)  
  19.     {  
  20.         if (Form1Event != null)  
  21.             Form1Event(this, EventArgs.Empty);  
  22.     }  
  23. }  
最后还需要在Program.cs中对Form1进行EventBroker的注册
  1. static void Main()  
  2. {  
  3.     Application.EnableVisualStyles();  
  4.     Application.SetCompatibleTextRenderingDefault(false);  
  5.   
  6.     //由于是单例模式,所有的EventBroker对象都是同一个  
  7.     var eventBroker = EventBrokerCreator.GetEventBroker();  
  8.     var form1 = new Form1();  
  9.     eventBroker.Register(form1);  
  10.   
  11.     Application.Run(form1);  
  12. }  
好了,大功告成了,有兴趣的人可以自己写个demo玩一下,个人觉得 eventBroker.Register(form1);这种注册的方式不够优雅,还有改进的余地。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值