恩,本人对EDA类库有几个基本的需求:
1、支持POCO,消息本身不能继承父类,这样利于序列化和远程传输
2、不能使用字符串作为消息标识,这样容易造成拼写错误
3、消息订阅和发布要尽量简单,易于使用
// 在此输入C代码 //订阅消息 CFMessage.Command.Subscribe((PasswordChanged d) => Debug.WriteLine(d.UserName)); //发布消息 CFMessage.Command.Publish(new PasswordChanged("zhangs", "123456", "654321"));
|
// 在此输入C代码 /// <summary> /// 消息管理 /// </summary> public static class CFMessage { private static Dictionary<string, ICFMessagePublisher> endpoints = new Dictionary<string, ICFMessagePublisher>(); private static object endpointsLocker = new object();
/// <summary> /// 获取事件通道的消息管理器 /// </summary> /// <returns></returns> public static ICFMessagePublisher Event { get { return GetInstance("Event"); } } /// <summary> /// 获取命令通道的消息管理器 /// </summary> /// <returns></returns> public static ICFMessagePublisher Command { get { return GetInstance("Command"); } } /// <summary> /// 获得指定通道的消息管理器 /// </summary> /// <param name="endpoint">消息通道</param> /// <returns></returns> public static ICFMessagePublisher GetInstance(string endpoint) { if (!endpoints.ContainsKey(endpoint)) { lock (endpointsLocker) { if (!endpoints.ContainsKey(endpoint)) endpoints.Add(endpoint, new CFMessagePublisher()); } } return endpoints[endpoint]; }
}
|
// 在此输入C代码 /// <summary> /// 消息发布管理 /// </summary> internal class CFMessagePublisher : ICFMessagePublisher { private Dictionary<Type, List<CFMessageSubscriber>> subscribers = new Dictionary<Type, List<CFMessageSubscriber>>(); private object subscribersLocker = new object(); /// <summary> /// 订阅同步消息 /// </summary> /// <typeparam name="T">消息类型</typeparam> /// <param name="domainEventSubscriber">消息响应</param> public void Subscribe<T>(Action<T> domainEventSubscriber) { this.Subscribe(new CFMessageSubscriber { EventType = typeof(T), EventHandler = domainEventSubscriber, IsAsnyc = false, }); } /// <summary> /// 订阅异步消息 /// </summary> /// <typeparam name="T">消息类型</typeparam> /// <param name="domainEventSubscriber">消息响应</param> public void SubscribeAsync<T>(Action<T> domainEventSubscriber) { this.Subscribe(new CFMessageSubscriber { EventType = typeof(T), EventHandler = domainEventSubscriber, IsAsnyc = true, }); } /// <summary> /// 订阅消息 /// </summary> /// <param name="domainEventSubscriber">消息响应</param> private void Subscribe(CFMessageSubscriber domainEventSubscriber) { if (!this.subscribers.ContainsKey(domainEventSubscriber.EventType)) { lock (this.subscribersLocker) { if (!this.subscribers.ContainsKey(domainEventSubscriber.EventType)) this.subscribers.Add(domainEventSubscriber.EventType, new List<CFMessageSubscriber>()); } } this.subscribers[domainEventSubscriber.EventType].Add(domainEventSubscriber); }
/// <summary> /// 发布消息 /// </summary> /// <typeparam name="T">消息类型</typeparam> /// <param name="domainEvent">消息体</param> public void Publish<T>(T domainEvent) { List<CFMessageSubscriber> subscriber = null; this.subscribers.TryGetValue(typeof(T), out subscriber); if (subscriber != null) { subscriber.ForEach(d => { Action<T> action = (Action<T>)d.EventHandler; if (d.IsAsnyc) action.BeginInvoke(domainEvent, ar => { try { action.EndInvoke(ar); } catch { } }, null); else action.Invoke(domainEvent); }); } }
/// <summary> /// 重置消息订阅队列 /// </summary> public void Reset() { this.subscribers.Clear(); } /// <summary> /// 重置指定类型的消息订阅队列 /// </summary> /// <typeparam name="T">消息类型</typeparam> public void Reset<T>() { Type type = typeof(T); if (this.subscribers.ContainsKey(type)) this.subscribers.Remove(type); }
}
|
// 在此输入C代码 /// <summary> /// 消息订阅管理 /// </summary> public class CFMessageSubscriber { /// <summary> /// 消息类型 /// </summary> public Type EventType { get; set; } /// <summary> /// 消息响应 /// </summary> public Delegate EventHandler { get; set; } /// <summary> /// 是否异步响应 /// </summary> public bool IsAsnyc { get; set; } }
|