我想创建一个非常简单的事件总线,它允许任何客户端订阅特定类型的事件,当任何发布者使用EventBus.PushEvent()
方法在总线上推送事件时,只有订阅该特定事件类型的客户端才能获得该事件.
我正在使用C#和.NET 2.0.
Tiny Messenger是一个不错的选择,我已经在现场项目中使用它已有2.5年了.来自Wiki的一些代码示例(链接如下):
出版
messageHub.Publish(new MyMessage());
订阅
messageHub.Subscribe((m) => { MessageBox.Show("Message Received!"); }); messageHub.Subscribe ((m) => { MessageBox.Show("Message Received!"); }, (m) => m.Content == "Testing");
代码在GitHub上:https://github.com/grumpydev/TinyMessenger
Wiki似乎仍然在BitBucket上:https://bitbucket.org/grumpydev/tinyioc/wiki/TinyMessenger
它还有一个Nuget包
Install-Package TinyMessenger
另一个,受到EventBus for android的启发,但更简单:
public class EventBus { public static EventBus Instance { get { return instance ?? (instance = new EventBus()); } } public void Register(object listener) { if (!listeners.Any(l => l.Listener == listener)) listeners.Add(new EventListenerWrapper(listener)); } public void Unregister(object listener) { listeners.RemoveAll(l => l.Listener == listener); } public void PostEvent(object e) { listeners.Where(l => l.EventType == e.GetType()).ToList().ForEach(l => l.PostEvent(e)); } private static EventBus instance; private EventBus() { } private Listlisteners = new List (); private class EventListenerWrapper { public object Listener { get; private set; } public Type EventType { get; private set; } private MethodBase method; public EventListenerWrapper(object listener) { Listener = listener; Type type = listener.GetType(); method = type.GetMethod("OnEvent"); if (method == null) throw new ArgumentException("Class " + type.Name + " does not containt method OnEvent"); ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length != 1) throw new ArgumentException("Method OnEvent of class " + type.Name + " have invalid number of parameters (should be one)"); EventType = parameters[0].ParameterType; } public void PostEvent(object e) { method.Invoke(Listener, new[] { e }); } } }
使用案例:
public class OnProgressChangedEvent { public int Progress { get; private set; } public OnProgressChangedEvent(int progress) { Progress = progress; } } public class SomeForm : Form { // ... protected override void OnLoad(EventArgs e) { base.OnLoad(e); EventBus.Instance.Register(this); } public void OnEvent(OnProgressChangedEvent e) { progressBar.Value = e.Progress; } protected override void OnClosed(EventArgs e) { base.OnClosed(e); EventBus.Instance.Unregister(this); } } public class SomeWorkerSomewhere { void OnDoWork() { // ... EventBus.Instance.PostEvent(new OnProgressChangedEvent(progress)); // ... } }