事件匯流排(在有些框架中也稱時間聚合器,如Prism的EventAggregater)是訂閱-發佈模式的一種實現,類似觀察者模式,相對於觀察者模式,事件匯流排更靈活,它是一種集中處理事件的模式,允許不同組件之間通信,降低耦合度。 事件匯流排的三要素:事件源(事件的定義)、發佈事件(觸發事件)、訂閱事件(事 ...
事件匯流排(在有些框架中也稱時間聚合器,如Prism的EventAggregater)是訂閱-發佈模式的一種實現,類似觀察者模式,相對於觀察者模式,事件匯流排更靈活,它是一種集中處理事件的模式,允許不同組件之間通信,降低耦合度。
事件匯流排的三要素:事件源(事件的定義)、發佈事件(觸發事件)、訂閱事件(事件的應答實現)。
實現事件匯流排,主要工作是事件基類、參數基類、事件自動註冊的定義,基於需求場景的業務型事件,只需要按照預定義的規則增加上述三要素即可,大大降低業務複雜度,且可實現一對一、一對多,多對一,同步應答、非同步應答等方式。
1、定義事件基類(抽象類)
public abstract class MyEventBase
{
public string EventName { get; set; }
}
2、事件參數的基類(抽象類)
public abstract class MyEventArgs<T>:EventArgs
{
public T Argument { get; set; }
}
3、事件的基類(無返回值的事件基類,因無返回值,可非同步調用,也可同步調用,建議非同步調用)
public class MyEvent<T>: MyEventBase where T : EventArgs
{
protected static readonly object lockObject = new object();
protected readonly List<Action<object, T>> subscribers = new List<Action<object, T>>();
public void Subscribe(Action<object, T> eventHandler)
{
lock (lockObject)
{
if (!subscribers.Contains(eventHandler))
{
subscribers.Add(eventHandler);
}
}
}
public void Unsubscribe(Action<object, T> eventHandler)
{
lock (lockObject)
{
if (subscribers.Contains(eventHandler))
{
subscribers.Remove(eventHandler);
}
}
}
public virtual void Publish(object sender, T eventArgs)
{
lock (lockObject)
{
for (int i = 0; i < subscribers.Count; i++)
{
subscribers[i](sender, eventArgs);
}
}
}
}
4、事件的基類(有返回值事件的基類,因需要獲取返回值,一般採用同步方式調用)
public class MyEventWithResult<T1, T2> : MyEventBase where T1 : EventArgs
{
protected static readonly object lockObject = new object();
protected readonly List<Func<object, T1, T2>> subscribers = new List<Func<object, T1, T2>>();
public void Subscribe(Func<object, T1, T2> eventHandler)
{
lock (lockObject)
{
if (!subscribers.Contains(eventHandler))
{
subscribers.Add(eventHandler);
}
}
}
public void Unsubscribe(Func<object, T1, T2> eventHandler)
{
lock (lockObject)
{
if (subscribers.Contains(eventHandler))
{
subscribers.Remove(eventHandler);
}
}
}
public virtual T2 Publish(object sender, T1 eventArgs)
{
T2 result = default;
lock (lockObject)
{
for (int i = 0; i < subscribers.Count; i++)
{
result = subscribers[i](sender, eventArgs);
}
}
return result;
}
}
5、事件中心,負責自動裝載事件
public class MyEventAggregator
{
private static MyEventAggregator _default;
private static readonly object _locker = new object();
private readonly Dictionary<Type, MyEventBase> _eventAggregator = new Dictionary<Type, MyEventBase>();
/// <summary>
/// 預設事件匯流排實例,建議只使用此實例
/// </summary>
public static MyEventAggregator Default
{
get
{
if (_default == null)
{
lock (_locker)
{
// 如果類的實例不存在則創建,否則直接返回
if (_default == null)
{
_default = new MyEventAggregator();
}
}
}
return _default;
}
}
/// <summary>
/// 構造函數,自動載入EventBase的派生類實現
/// </summary>
public MyEventAggregator()
{
Type type = typeof(MyEventBase);
Assembly assembly = Assembly.GetAssembly(type);
//註冊時需排除的基類
Type typeMyEvent = typeof(MyEvent<>);
Type typeMyEventWithResult = typeof(MyEventWithResult<,>);
List<Type> typeList2 = assembly.GetTypes()
.Where(t => t != type && t!=typeAnalysisEvent && t != typeMyEventWithResult && type.IsAssignableFrom(t))
.ToList();
foreach (var item in typeList2)
{
MyEventBase eventBase = (MyEventBase)assembly.CreateInstance(item.FullName);
_eventAggregator.Add(item, eventBase);
}
}
/// <summary>
/// 獲取事件實例
/// </summary>
/// <typeparam name="TEvent">事件類型</typeparam>
/// <returns></returns>
public TEvent GetEvent<TEvent>() where TEvent : MyEventBase
{
return (TEvent)_eventAggregator[typeof(TEvent)];
}
/// <summary>
/// 添加事件類型
/// </summary>
/// <typeparam name="TEvent"></typeparam>
public void AddEvent<TEvent>() where TEvent : MyEventBase, new()
{
lock (_locker)
{
Type type = typeof(TEvent);
if (!_eventAggregator.ContainsKey(type))
{
_eventAggregator.Add(type, new TEvent());
}
}
}
/// <summary>
/// 移除事件類型
/// </summary>
/// <typeparam name="TEvent"></typeparam>
public void RemoveEvent<TEvent>() where TEvent : MyEventBase, new()
{
lock (_locker)
{
Type type = typeof(TEvent);
if (_eventAggregator.ContainsKey(type))
{
_eventAggregator.Remove(type);
}
}
}
}
}
6、具體事件的定義和調用示例
定義
/// <summary>
/// 添加日誌 事件
/// </summary>
public class WriteLogEvent : MyEvent<WriteLogEventArgs>
{
public override void Publish(object sender, WriteLogEventArgs eventArgs)
{
for (int i = 0; i < subscribers.Count; i++)
{
var action = subscribers[i];
Task.Run(() => action(sender, eventArgs));
}
}
}
public class WriteLogEventArgs : MyEventArgs<WriteLogEventArgs2> { };
public class WriteLogEventArgs2
{
/// <summary>
/// 日誌內容
/// </summary>
public string Msg { get; set; }
/// <summary>
/// 操作類型
/// </summary>
public OperationType OperationType { get; set; }
/// <summary>
/// 備註
/// </summary>
public string Remark { get; set; }
/// <summary>
/// 目標類型
/// </summary>
public LogTargetType LogTargetType { get; set; }
/// <summary>
/// 目標值
/// </summary>
public string TargetValue { get; set; }
}
發佈事件
MyEventAggregator.Default.GetEvent<WriteLogEvent>().Publish(this, new WriteLogEventArgs
{
Argument = new WriteLogEventArgs2
{
Msg = logMsg,
OperationType = OperationType.Save,
LogTargetType = LogTargetType.OriginalData,
TargetValue = targetValue,
Remark = _MPIComment
}
});
訂閱事件
MyEventAggregator.Default.GetEvent<WriteLogEvent>().Subscribe(WriteLogEventHandler);
private void WriteLogEventHandler(object sender, WriteLogEventArgs e)
{
-----business logic
-----
}
本文來自博客園,作者:GIS民工,轉載請註明原文鏈接:https://www.cnblogs.com/kook2007/p/18379352