123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525 |
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.Linq;
- using System.Threading.Tasks;
- namespace EventBus
- {
- public sealed class EventBroker : IEventBroker,IDisposable
- {
- private static readonly Lazy<EventBroker> _eventBroker = new Lazy<EventBroker>(() => new EventBroker());
- private EventBroker()
- {
- }
- string GetHash()
- {
- return DateTime.Now.ToLongTimeString();
- }
- public static EventBroker Instance => _eventBroker.Value;
- private readonly Dictionary<Type, List<IBaseEventData>> _list = new Dictionary<Type, List<IBaseEventData>>();
- private bool disposedValue;
- public IEventData<TData, T> GetEvent<TData, T>()
- {
- lock (_list)
- {
- if (_list.TryGetValue(typeof(EventData<TData, T>), out List<IBaseEventData>? baseevent))
- {
- baseevent ??= new List<IBaseEventData>();
- if (baseevent.Count == 0) baseevent.Add(new EventData<TData, T>(GetHash()));
- return (IEventData<TData, T>)baseevent.First();
- }
- else
- {
- EventData<TData, T> eventData = new EventData<TData, T>(GetHash());
- _list.Add(typeof(EventData<TData, T>), new List<IBaseEventData>() { eventData });
- return eventData;
- }
- }
- }
- public IAnonymousEventData GetEvent(string eventName)
- {
- lock (_list)
- {
- ArgumentNullException.ThrowIfNullOrEmpty(eventName);
- if (_list.TryGetValue(typeof(IAnonymousEventData), out List<IBaseEventData>? baseevent))
- {
- baseevent ??= new List<IBaseEventData>();
- if (!baseevent.Where(x => x is AnonymousEventData && x.EventName.Contains(eventName)).Any()) baseevent.Add(new AnonymousEventData(eventName, GetHash()));
- return (IAnonymousEventData)baseevent.Where(x => x is AnonymousEventData && (x as AnonymousEventData)!.EventName.Contains(eventName)).First();
- }
- else
- {
- AnonymousEventData eventData = new AnonymousEventData(eventName, GetHash());
- _list.Add(typeof(IAnonymousEventData), new List<IBaseEventData>() { eventData });
- return eventData;
- }
- }
- }
- public IAnonymousEventData<T> GetEvent<T>(string eventName)
- {
- lock (_list)
- {
- ArgumentNullException.ThrowIfNullOrEmpty(eventName);
- if (_list.TryGetValue(typeof(IAnonymousEventData), out List<IBaseEventData>? baseevent))
- {
- baseevent ??= new List<IBaseEventData>();
- if (!baseevent.Where(x => x is AnonymousEventData<T> && x.EventName.Contains(eventName)).Any()) baseevent.Add(new AnonymousEventData<T>(eventName, GetHash()));
- return (IAnonymousEventData<T>)baseevent.Where(x => x is AnonymousEventData<T> && (x as AnonymousEventData<T>)!.EventName.Contains(eventName)).First();
- }
- else
- {
- AnonymousEventData<T> eventData = new AnonymousEventData<T>(eventName, GetHash());
- _list.Add(typeof(IAnonymousEventData), [eventData]);
- return eventData;
- }
- }
- }
- public IEventData<TData> GetEvent<TData>()
- {
- lock (_list)
- {
- if (_list.TryGetValue(typeof(EventData<TData>), out List<IBaseEventData>? baseevent))
- {
- baseevent ??= new List<IBaseEventData>();
- if (baseevent.Count == 0) baseevent.Add(new EventData<TData>(GetHash()));
- return (IEventData<TData>)baseevent.First();
- }
- else
- {
- EventData<TData> eventData = new EventData<TData>(GetHash());
- _list.Add(typeof(EventData<TData>), new List<IBaseEventData>() { eventData });
- return eventData;
- }
- }
- }
- internal abstract class BaseValue
- {
- public BaseValue(Properties? properties = null)
- {
- this.Properties = properties ?? Properties.Default;
- this.IntPtr = Guid.NewGuid();
- }
- public DateTime DateTime => DateTime.Now;
- private Properties properties = Properties.Default;
- public Properties Properties { get => properties ?? Properties.Default; private set => properties = value; }
- public abstract bool HasDelegate { get; }
- public Guid IntPtr { get; internal set; }
- }
- internal class ActionValue<TData> :BaseValue
- {
- public ActionValue(Action<object, EventArgs<TData>> action, Properties? properties = null):base(properties)
- {
- this.Action = action;
- }
- internal Action<object, EventArgs<TData>> Action { get; set; }
- public override bool HasDelegate => Action != null;
- public bool Invoke(object sender,TData args,IBaseEventData eventData)
- {
- if (Action == null) return false;
- var eventargs = new EventArgs<TData>(args, Instance, IntPtr, eventData);
- Action.Invoke(sender, eventargs);
- return eventargs.Handle;
- }
- }
- internal abstract class BaseFuncValue<TData,TResult>:BaseValue
- {
- public BaseFuncValue(Properties? properties = null):base(properties)
- {
- }
- public abstract TResult Invoke(object sender, TData data, IBaseEventData eventData);
- public abstract List<TResult> InvokeList(object sender, TData data, IBaseEventData eventData);
- public abstract bool IsListFunc { get; }
- }
- internal class FuncValue<TData,TRestlt> : BaseFuncValue<TData,TRestlt>
- {
- public FuncValue(Func<object, EventArgs<TData>, TRestlt> func, Properties? properties = null):base(properties)
- {
- Func = func;
- }
- internal Func<object, EventArgs<TData>, TRestlt> Func { get; private set; }
- public override bool IsListFunc => false;
- public override bool HasDelegate => Func!=null;
- public override TRestlt Invoke(object sender, TData data, IBaseEventData eventData)
- {
- ArgumentNullException.ThrowIfNull(Func);
- return Func.Invoke(sender, new EventArgs<TData>(data, Instance, IntPtr, eventData, typeof(TRestlt)));
- }
- public override List<TRestlt> InvokeList(object sender, TData data, IBaseEventData eventData)
- {
- throw new NotImplementedException();
- }
- }
- internal class ListFuncValue<TData, TRestlt> : BaseFuncValue<TData,TRestlt>
- {
- public ListFuncValue(Func<object, EventArgs<TData>, List<TRestlt>> func, Properties? properties = null) : base( properties)
- {
- Func = func;
- }
- public Func<object, EventArgs<TData>, List<TRestlt>> Func { get; private set; }
- public override bool IsListFunc => true;
- public override bool HasDelegate => Func != null;
- public override TRestlt Invoke(object sender, TData data, IBaseEventData eventData)
- {
- throw new NotImplementedException();
- }
- public override List<TRestlt> InvokeList(object sender, TData data, IBaseEventData eventData)
- {
- ArgumentNullException.ThrowIfNull(Func);
- return Func.Invoke(sender, new EventArgs<TData>(data, Instance, IntPtr, eventData, typeof(TRestlt)));
- }
- }
- public sealed class EventData<TData> : IEventData<TData>
- {
- public string EventName { get; }
- public string Hash { get; }
- internal EventData(string eventName,string hash)
- {
- EventName = eventName;
- Hash = hash;
- }
- internal EventData(string hash) : this(hash, hash)
- {
- }
- ConcurrentDictionary<Guid, ActionValue<TData>> _list = new ConcurrentDictionary<Guid, ActionValue<TData>>();
- public void Publish(object sender, TData data, Properties? properties = null)
- {
- try
- {
- ArgumentNullException.ThrowIfNull(data);
- properties ??= Properties.Default;
- if (_list.IsEmpty) return;
- var templist = _list.Where(x => x.Value.Properties.FilterRule(properties) && x.Value.HasDelegate).Select(x => x.Value).ToList();
- if (templist.Count == 0) return;
- foreach (var val in templist)
- {
- if (val.Invoke(sender, data, this)) return;
- }
- }
- catch
- {
- }
- }
- public void UnSubscrip(Guid guid)
- {
- lock (_list)
- {
- if (guid == Guid.Empty) return;
- _list.TryRemove(guid,out _);
- }
- }
- public Guid Subscrip(Action<object, EventArgs<TData>> action, Properties? properties = null)
- {
- lock (_list)
- {
- ArgumentNullException.ThrowIfNull(action);
- properties ??= Properties.Default;
- var temp = new ActionValue<TData>(action, properties);
- _list[temp.IntPtr] = temp;
- return temp.IntPtr;
- }
- }
- public void Clear()
- {
- lock (_list)
- {
- _list.Clear();
- }
- }
- public async Task PublishAsync(object sender, TData data, Properties? properties = null)
- {
- try
- {
- ArgumentNullException.ThrowIfNull(data);
- properties ??= Properties.Default;
- if (_list.IsEmpty) return;
- var temp = _list.Where(x => x.Value.Properties.FilterRule(properties) && x.Value.HasDelegate).Select(x => x.Value).ToList();
- if (temp.Count == 0) return;
- foreach (var val in temp)
- {
- if (await Task.Run(() => val.Invoke(sender, data, this))) return;
- }
- }
- catch
- {
- }
- }
- }
- public sealed class EventData<TData, T> : IEventData<TData, T>
- {
- public string EventName { get; }
- public string Hash { get; }
- private readonly ConcurrentDictionary<Guid,BaseFuncValue<TData,T>> _list = new ConcurrentDictionary<Guid,BaseFuncValue<TData, T>>();
- internal EventData(string eventName, string hash)
- {
- EventName = eventName;
- Hash = hash;
- }
- internal EventData(string hash) : this(hash, hash)
- {
- }
- public T Publish(object sender, TData data, Properties? properties = null)
- {
- ArgumentNullException.ThrowIfNull(data);
- if (_list.IsEmpty) return Activator.CreateInstance<T>();
- properties ??= Properties.Default;
- var func = _list.Where(x=>x.Value is FuncValue<TData,T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x=>x.Value).ToList();
- if (func.Count == 0) return Activator.CreateInstance<T>();
- return func.First().Invoke(sender, data, this);
- }
- public List<T> PublishList(object sender, TData data, Properties? properties = null)
- {
- ArgumentNullException.ThrowIfNull(data);
- if (_list.IsEmpty) return new List<T>();
- properties ??= Properties.Default;
- var func = _list.Where(x => x.Value is ListFuncValue<TData, T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x => x.Value).ToList();
- if (func.Count == 0) return new List<T>();
- return func.First().InvokeList(sender, data, this);
- }
- public Guid Subscrip(Func<object, EventArgs<TData>, T> func, Properties? properties = null)
- {
- ArgumentNullException.ThrowIfNull(func);
- properties ??= Properties.Default;
- var temp = new FuncValue<TData, T>(func, properties);
- _list[temp.IntPtr] = temp;
- return temp.IntPtr;
- }
- public Guid SubscripList( Func<object, EventArgs<TData>, List<T>> func, Properties? properties = null)
- {
- ArgumentNullException.ThrowIfNull(func);
- properties ??= Properties.Default;
- var temp = new ListFuncValue<TData, T>(func, properties);
- _list[temp.IntPtr] = temp;
- return temp.IntPtr;
- }
- public void UnSubscrip(Guid intPtr)
- {
- if (intPtr == Guid.Empty) return;
- _list.TryRemove(intPtr,out var _);
- }
- public void Clear()
- {
- _list.Clear();
- }
- public async Task<T> PublishAsync(object sender, TData data, Properties? properties = null)
- {
- ArgumentNullException.ThrowIfNull(data);
- if (_list.IsEmpty) return Activator.CreateInstance<T>();
- properties ??= Properties.Default;
- var func = _list.Where(x => x.Value is FuncValue<TData, T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x => x.Value).ToList();
- if (func.Count == 0) return Activator.CreateInstance<T>();
- return await Task.Run(()=> func.First().Invoke(sender, data, this));
- }
- public async Task<List<T>> PublishListAsync(object sender, TData data, Properties? properties = null)
- {
- ArgumentNullException.ThrowIfNull(data);
- if (_list.IsEmpty) return new List<T>();
- properties ??= Properties.Default;
- var func = _list.Where(x => x.Value is ListFuncValue<TData, T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x => x.Value).ToList();
- if (func.Count == 0) return new List<T>();
- return await Task.Run(() => func.First().InvokeList(sender, data, this));
- }
- }
- public sealed class AnonymousEventData : IAnonymousEventData
- {
- public string EventName { get; }
- public string Hash { get; }
- internal AnonymousEventData(string eventName, string hash)
- {
- EventName = eventName;
- Hash = hash;
- }
- internal AnonymousEventData(string hash) : this(hash, hash)
- {
- }
- ConcurrentDictionary<Guid, ActionValue<object[]>> _list = new ConcurrentDictionary<Guid, ActionValue<object[]>>();
- public void Publish(object sender, Properties? properties, params object[] data)
- {
-
- properties ??= Properties.Default;
- if (_list.IsEmpty) return;
- var templist = _list.Where(x => x.Value.Properties.FilterRule(properties) && x.Value.HasDelegate).ToList();
- if (templist.Count == 0) return;
- foreach (var val in templist)
- {
- var args = new EventArgs<object[]>(data, Instance, val.Value.IntPtr,this);
- val.Value.Action.Invoke(sender, args);
- if (args.Handle) return;
- }
- }
- public void UnSubscrip(Guid guid)
- {
- if (guid == Guid.Empty) return;
- _list.TryRemove(guid, out _);
- }
- public Guid Subscrip(Action<object, EventArgs<object[]>> action, Properties? properties=null)
- {
- ArgumentNullException.ThrowIfNull(action);
- properties ??= Properties.Default;
- var act = new ActionValue<object[]>(action, properties);
- _list[act.IntPtr] = act;
- return act.IntPtr;
- }
- public void Clear() => _list.Clear();
- public async Task PublishAsync(object sender, Properties? properties = null, params object[] data)
- {
- properties ??= Properties.Default;
- if (_list.IsEmpty) return;
- var templist = _list.Where(x => x.Value.Properties.FilterRule(properties) && x.Value.HasDelegate).Select(x => x.Value).ToList();
- foreach (var val in templist)
- {
- var args = new EventArgs<object[]>(data, Instance, val.IntPtr, this);
- await System.Threading.Tasks.Task.Run(() => val.Action.Invoke(sender, args));
- if (args.Handle) return;
- }
- }
- }
- public sealed class AnonymousEventData<T> : IAnonymousEventData<T>
- {
- public string EventName { get; }
- public string Hash { get; }
- ConcurrentDictionary<Guid,BaseFuncValue<object[], T>> _list = new ConcurrentDictionary<Guid, BaseFuncValue<object[], T>>();
- internal AnonymousEventData(string eventName, string hash)
- {
- EventName = eventName;
- Hash = hash;
- }
- internal AnonymousEventData(string hash) : this(hash, hash)
- {
- }
- public T Publish(object sender, Properties? properties, params object[] data)
- {
- if (_list.IsEmpty) return Activator.CreateInstance<T>();
- properties ??= Properties.Default;
- var func = _list.Where(x => x.Value is FuncValue<object[], T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x=>x.Value).ToList();
- if (func.Count == 0) return Activator.CreateInstance<T>();
- return func.First().Invoke(sender, data, this);
- }
- public List<T> PublishList(object sender, Properties? properties, params object[] data)
- {
- if (_list.IsEmpty) return new List<T>();
- properties ??= Properties.Default;
- var func = _list.Where(x => x.Value is ListFuncValue<object[], T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x => x.Value).ToList();
- if (func.Count == 0) return new List<T>();
- return func.First().InvokeList(sender, data, this);
- }
- public Guid Subscrip(Func<object, EventArgs<object[]>, T> func, Properties? properties=null)
- {
- ArgumentNullException.ThrowIfNull(func);
- properties ??= Properties.Default;
- var tempfunc = new FuncValue<object[], T>(func, properties);
- _list[tempfunc.IntPtr] = tempfunc;
- return tempfunc.IntPtr;
- }
- public Guid SubscripList(Func<object, EventArgs<object[]>, List<T>> func, Properties? properties=null)
- {
- ArgumentNullException.ThrowIfNull(func);
- properties ??= Properties.Default;
- var tempfunc = new ListFuncValue<object[], T>(func, properties);
- _list[tempfunc.IntPtr] = tempfunc;
- return tempfunc.IntPtr;
- }
- public void UnSubscrip(Guid guid)
- {
- if (guid == Guid.Empty) return;
- _list.TryRemove(guid, out _);
- }
- public void Clear()
- {
- _list.Clear();
- }
- public async Task<T> PublishAsync(object sender, Properties? properties = null, params object[] data)
- {
- if (_list.IsEmpty) return Activator.CreateInstance<T>();
- properties ??= Properties.Default;
- var func = _list.Where(x => x.Value is FuncValue<object[], T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x=>x.Value).ToList();
- if (func.Count == 0) return Activator.CreateInstance<T>();
- return await Task.Run(()=> func.First().Invoke(sender, data, this));
- }
- public async Task<List<T>> PublishListAsync(object sender, Properties? properties = null, params object[] data)
- {
- if (_list.IsEmpty) return new List<T>();
- properties ??= Properties.Default;
- var func = _list.Where(x => x.Value is ListFuncValue<object[], T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x => x.Value).ToList();
- if (func.Count == 0) return new List<T>();
- return await Task.Run(()=> func.First().InvokeList(sender, data, this));
- }
- }
- private void Dispose(bool disposing)
- {
- if (!disposedValue)
- {
- if (disposing)
- {
- _list.Values.ToList().ForEach(x => x?.ToList().ForEach(y=>y.Clear()));
- _list.Clear();
- }
- // TODO: 释放未托管的资源(未托管的对象)并替代终结器
- // TODO: 将大型字段设置为 null
- disposedValue = true;
- }
- }
- // // TODO: 仅当“Dispose(bool disposing)”拥有用于释放未托管资源的代码时才替代终结器
- // ~EventBroker()
- // {
- // // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
- // Dispose(disposing: false);
- // }
- public void Dispose()
- {
- // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
- Dispose(disposing: true);
- GC.SuppressFinalize(this);
- }
- }
- }
|