我为这样的场景实现了一个简单的 EventBroker。但是,我不认为注射会是一团糟。事实上,将其注入容器然后解析发布/订阅将是最简洁的方式。单元测试也会更容易。下面给出了我的事件代理(我使用的是 MEF,但这几乎不会产生任何影响):-
[Export]
public class MyEventBroker : IMyEventBroker
{
[ImportingConstructor]
public MyEventBroker()
{
}
private readonly ConcurrentDictionary<Type, List<Action<CompositeEventArguments>>> _compositeEventHandlers = new ConcurrentDictionary<Type, List<Action<CompositeEventArguments>>>();
public void Publish<T>(CompositeEventArguments args)
{
if (_compositeEventHandlers.ContainsKey(typeof (T)))
{
_compositeEventHandlers[typeof(T)].ForEach(subscriber=> { if (subscriber != null) subscriber.Invoke(args); }); //TODO : check for null. QUES - Will we need weak references?????
}
}
public void Subscribe<T>(Action<CompositeEventArguments> handler)
{
if (!_compositeEventHandlers.ContainsKey(typeof (T)))
_compositeEventHandlers[typeof(T)] = new List<Action<CompositeEventArguments>>();
_compositeEventHandlers[typeof (T)].Add(handler);
}
public void UnSubscribe<T>(Action<CompositeEventArguments> handler)
{
if (_compositeEventHandlers.ContainsKey(typeof (T)))
_compositeEventHandlers[typeof (T)].Remove(handler);
}
}
public class CompositeEvent<T> where T : CompositeEventArguments
{
}
public class CompositeEventArguments
{
}
现在要拥有您的自定义事件,请定义您的事件参数:-
#region Custom Events
public class MyCustomEventArgs : CompositeEventArguments{}
#endregion
然后发布:-
var broker = MefContainer.Instance.Resolve<MyEventBroker>();
broker.Publish<MyCustomEventArgs >(new MyCustomEventArgs());
并订阅:-
var broker = MefContainer.Instance.Resolve<MyEventBroker>();
broker.Subscribe<MyCustomEventArgs >(t=>MyHandler(t));
MefContainer 是我的自定义单例类,用于公开组合容器。你可以使用统一,温莎或任何你喜欢的!
在这里写博客:http: //compositewinform.blogspot.co.uk/2014/04/have-you-ever-found-yourself-in.html