EventBroker.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.Diagnostics.CodeAnalysis;
  5. using System.Linq;
  6. using System.Threading.Tasks;
  7. namespace EventBus
  8. {
  9. public sealed class EventBroker : IEventBroker,IDisposable
  10. {
  11. private static readonly Lazy<EventBroker> _eventBroker = new Lazy<EventBroker>(() => new EventBroker());
  12. private EventBroker()
  13. {
  14. }
  15. string GetHash()
  16. {
  17. return DateTime.Now.ToLongTimeString();
  18. }
  19. public static EventBroker Instance => _eventBroker.Value;
  20. private readonly Dictionary<Type, List<IBaseEventData>> _list = new Dictionary<Type, List<IBaseEventData>>();
  21. private bool disposedValue;
  22. public IEventData<TData, T> GetEvent<TData, T>()
  23. {
  24. lock (_list)
  25. {
  26. if (_list.TryGetValue(typeof(EventData<TData, T>), out List<IBaseEventData>? baseevent))
  27. {
  28. baseevent ??= new List<IBaseEventData>();
  29. if (baseevent.Count == 0) baseevent.Add(new EventData<TData, T>(GetHash()));
  30. return (IEventData<TData, T>)baseevent.First();
  31. }
  32. else
  33. {
  34. EventData<TData, T> eventData = new EventData<TData, T>(GetHash());
  35. _list.Add(typeof(EventData<TData, T>), new List<IBaseEventData>() { eventData });
  36. return eventData;
  37. }
  38. }
  39. }
  40. public IAnonymousEventData GetEvent(string eventName)
  41. {
  42. lock (_list)
  43. {
  44. ArgumentNullException.ThrowIfNullOrEmpty(eventName);
  45. if (_list.TryGetValue(typeof(IAnonymousEventData), out List<IBaseEventData>? baseevent))
  46. {
  47. baseevent ??= new List<IBaseEventData>();
  48. if (!baseevent.Where(x => x is AnonymousEventData && x.EventName.Contains(eventName)).Any()) baseevent.Add(new AnonymousEventData(eventName, GetHash()));
  49. return (IAnonymousEventData)baseevent.Where(x => x is AnonymousEventData && (x as AnonymousEventData)!.EventName.Contains(eventName)).First();
  50. }
  51. else
  52. {
  53. AnonymousEventData eventData = new AnonymousEventData(eventName, GetHash());
  54. _list.Add(typeof(IAnonymousEventData), new List<IBaseEventData>() { eventData });
  55. return eventData;
  56. }
  57. }
  58. }
  59. public IAnonymousEventData<T> GetEvent<T>(string eventName)
  60. {
  61. lock (_list)
  62. {
  63. ArgumentNullException.ThrowIfNullOrEmpty(eventName);
  64. if (_list.TryGetValue(typeof(IAnonymousEventData), out List<IBaseEventData>? baseevent))
  65. {
  66. baseevent ??= new List<IBaseEventData>();
  67. if (!baseevent.Where(x => x is AnonymousEventData<T> && x.EventName.Contains(eventName)).Any()) baseevent.Add(new AnonymousEventData<T>(eventName, GetHash()));
  68. return (IAnonymousEventData<T>)baseevent.Where(x => x is AnonymousEventData<T> && (x as AnonymousEventData<T>)!.EventName.Contains(eventName)).First();
  69. }
  70. else
  71. {
  72. AnonymousEventData<T> eventData = new AnonymousEventData<T>(eventName, GetHash());
  73. _list.Add(typeof(IAnonymousEventData), [eventData]);
  74. return eventData;
  75. }
  76. }
  77. }
  78. public IEventData<TData> GetEvent<TData>()
  79. {
  80. lock (_list)
  81. {
  82. if (_list.TryGetValue(typeof(EventData<TData>), out List<IBaseEventData>? baseevent))
  83. {
  84. baseevent ??= new List<IBaseEventData>();
  85. if (baseevent.Count == 0) baseevent.Add(new EventData<TData>(GetHash()));
  86. return (IEventData<TData>)baseevent.First();
  87. }
  88. else
  89. {
  90. EventData<TData> eventData = new EventData<TData>(GetHash());
  91. _list.Add(typeof(EventData<TData>), new List<IBaseEventData>() { eventData });
  92. return eventData;
  93. }
  94. }
  95. }
  96. internal abstract class BaseValue
  97. {
  98. public BaseValue(Properties? properties = null)
  99. {
  100. this.Properties = properties ?? Properties.Default;
  101. this.IntPtr = Guid.NewGuid();
  102. }
  103. public DateTime DateTime => DateTime.Now;
  104. private Properties properties = Properties.Default;
  105. public Properties Properties { get => properties ?? Properties.Default; private set => properties = value; }
  106. public abstract bool HasDelegate { get; }
  107. public Guid IntPtr { get; internal set; }
  108. }
  109. internal class ActionValue<TData> :BaseValue
  110. {
  111. public ActionValue(Action<object, EventArgs<TData>> action, Properties? properties = null):base(properties)
  112. {
  113. this.Action = action;
  114. }
  115. internal Action<object, EventArgs<TData>> Action { get; set; }
  116. public override bool HasDelegate => Action != null;
  117. public bool Invoke(object sender,TData args,IBaseEventData eventData)
  118. {
  119. if (Action == null) return false;
  120. var eventargs = new EventArgs<TData>(args, Instance, IntPtr, eventData);
  121. Action.Invoke(sender, eventargs);
  122. return eventargs.Handle;
  123. }
  124. }
  125. internal abstract class BaseFuncValue<TData,TResult>:BaseValue
  126. {
  127. public BaseFuncValue(Properties? properties = null):base(properties)
  128. {
  129. }
  130. public abstract TResult Invoke(object sender, TData data, IBaseEventData eventData);
  131. public abstract List<TResult> InvokeList(object sender, TData data, IBaseEventData eventData);
  132. public abstract bool IsListFunc { get; }
  133. }
  134. internal class FuncValue<TData,TRestlt> : BaseFuncValue<TData,TRestlt>
  135. {
  136. public FuncValue(Func<object, EventArgs<TData>, TRestlt> func, Properties? properties = null):base(properties)
  137. {
  138. Func = func;
  139. }
  140. internal Func<object, EventArgs<TData>, TRestlt> Func { get; private set; }
  141. public override bool IsListFunc => false;
  142. public override bool HasDelegate => Func!=null;
  143. public override TRestlt Invoke(object sender, TData data, IBaseEventData eventData)
  144. {
  145. ArgumentNullException.ThrowIfNull(Func);
  146. return Func.Invoke(sender, new EventArgs<TData>(data, Instance, IntPtr, eventData, typeof(TRestlt)));
  147. }
  148. public override List<TRestlt> InvokeList(object sender, TData data, IBaseEventData eventData)
  149. {
  150. throw new NotImplementedException();
  151. }
  152. }
  153. internal class ListFuncValue<TData, TRestlt> : BaseFuncValue<TData,TRestlt>
  154. {
  155. public ListFuncValue(Func<object, EventArgs<TData>, List<TRestlt>> func, Properties? properties = null) : base( properties)
  156. {
  157. Func = func;
  158. }
  159. public Func<object, EventArgs<TData>, List<TRestlt>> Func { get; private set; }
  160. public override bool IsListFunc => true;
  161. public override bool HasDelegate => Func != null;
  162. public override TRestlt Invoke(object sender, TData data, IBaseEventData eventData)
  163. {
  164. throw new NotImplementedException();
  165. }
  166. public override List<TRestlt> InvokeList(object sender, TData data, IBaseEventData eventData)
  167. {
  168. ArgumentNullException.ThrowIfNull(Func);
  169. return Func.Invoke(sender, new EventArgs<TData>(data, Instance, IntPtr, eventData, typeof(TRestlt)));
  170. }
  171. }
  172. public sealed class EventData<TData> : IEventData<TData>
  173. {
  174. public string EventName { get; }
  175. public string Hash { get; }
  176. internal EventData(string eventName,string hash)
  177. {
  178. EventName = eventName;
  179. Hash = hash;
  180. }
  181. internal EventData(string hash) : this(hash, hash)
  182. {
  183. }
  184. ConcurrentDictionary<Guid, ActionValue<TData>> _list = new ConcurrentDictionary<Guid, ActionValue<TData>>();
  185. public void Publish(object sender, TData data, Properties? properties = null)
  186. {
  187. try
  188. {
  189. ArgumentNullException.ThrowIfNull(data);
  190. properties ??= Properties.Default;
  191. if (_list.IsEmpty) return;
  192. var templist = _list.Where(x => x.Value.Properties.FilterRule(properties) && x.Value.HasDelegate).Select(x => x.Value).ToList();
  193. if (templist.Count == 0) return;
  194. foreach (var val in templist)
  195. {
  196. if (val.Invoke(sender, data, this)) return;
  197. }
  198. }
  199. catch
  200. {
  201. }
  202. }
  203. public void UnSubscrip(Guid guid)
  204. {
  205. lock (_list)
  206. {
  207. if (guid == Guid.Empty) return;
  208. _list.TryRemove(guid,out _);
  209. }
  210. }
  211. public Guid Subscrip(Action<object, EventArgs<TData>> action, Properties? properties = null)
  212. {
  213. lock (_list)
  214. {
  215. ArgumentNullException.ThrowIfNull(action);
  216. properties ??= Properties.Default;
  217. var temp = new ActionValue<TData>(action, properties);
  218. _list[temp.IntPtr] = temp;
  219. return temp.IntPtr;
  220. }
  221. }
  222. public void Clear()
  223. {
  224. lock (_list)
  225. {
  226. _list.Clear();
  227. }
  228. }
  229. public async Task PublishAsync(object sender, TData data, Properties? properties = null)
  230. {
  231. try
  232. {
  233. ArgumentNullException.ThrowIfNull(data);
  234. properties ??= Properties.Default;
  235. if (_list.IsEmpty) return;
  236. var temp = _list.Where(x => x.Value.Properties.FilterRule(properties) && x.Value.HasDelegate).Select(x => x.Value).ToList();
  237. if (temp.Count == 0) return;
  238. foreach (var val in temp)
  239. {
  240. if (await Task.Run(() => val.Invoke(sender, data, this))) return;
  241. }
  242. }
  243. catch
  244. {
  245. }
  246. }
  247. }
  248. public sealed class EventData<TData, T> : IEventData<TData, T>
  249. {
  250. public string EventName { get; }
  251. public string Hash { get; }
  252. private readonly ConcurrentDictionary<Guid,BaseFuncValue<TData,T>> _list = new ConcurrentDictionary<Guid,BaseFuncValue<TData, T>>();
  253. internal EventData(string eventName, string hash)
  254. {
  255. EventName = eventName;
  256. Hash = hash;
  257. }
  258. internal EventData(string hash) : this(hash, hash)
  259. {
  260. }
  261. public T Publish(object sender, TData data, Properties? properties = null)
  262. {
  263. ArgumentNullException.ThrowIfNull(data);
  264. if (_list.IsEmpty) return Activator.CreateInstance<T>();
  265. properties ??= Properties.Default;
  266. 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();
  267. if (func.Count == 0) return Activator.CreateInstance<T>();
  268. return func.First().Invoke(sender, data, this);
  269. }
  270. public List<T> PublishList(object sender, TData data, Properties? properties = null)
  271. {
  272. ArgumentNullException.ThrowIfNull(data);
  273. if (_list.IsEmpty) return new List<T>();
  274. properties ??= Properties.Default;
  275. 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();
  276. if (func.Count == 0) return new List<T>();
  277. return func.First().InvokeList(sender, data, this);
  278. }
  279. public Guid Subscrip(Func<object, EventArgs<TData>, T> func, Properties? properties = null)
  280. {
  281. ArgumentNullException.ThrowIfNull(func);
  282. properties ??= Properties.Default;
  283. var temp = new FuncValue<TData, T>(func, properties);
  284. _list[temp.IntPtr] = temp;
  285. return temp.IntPtr;
  286. }
  287. public Guid SubscripList( Func<object, EventArgs<TData>, List<T>> func, Properties? properties = null)
  288. {
  289. ArgumentNullException.ThrowIfNull(func);
  290. properties ??= Properties.Default;
  291. var temp = new ListFuncValue<TData, T>(func, properties);
  292. _list[temp.IntPtr] = temp;
  293. return temp.IntPtr;
  294. }
  295. public void UnSubscrip(Guid intPtr)
  296. {
  297. if (intPtr == Guid.Empty) return;
  298. _list.TryRemove(intPtr,out var _);
  299. }
  300. public void Clear()
  301. {
  302. _list.Clear();
  303. }
  304. public async Task<T> PublishAsync(object sender, TData data, Properties? properties = null)
  305. {
  306. ArgumentNullException.ThrowIfNull(data);
  307. if (_list.IsEmpty) return Activator.CreateInstance<T>();
  308. properties ??= Properties.Default;
  309. 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();
  310. if (func.Count == 0) return Activator.CreateInstance<T>();
  311. return await Task.Run(()=> func.First().Invoke(sender, data, this));
  312. }
  313. public async Task<List<T>> PublishListAsync(object sender, TData data, Properties? properties = null)
  314. {
  315. ArgumentNullException.ThrowIfNull(data);
  316. if (_list.IsEmpty) return new List<T>();
  317. properties ??= Properties.Default;
  318. 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();
  319. if (func.Count == 0) return new List<T>();
  320. return await Task.Run(() => func.First().InvokeList(sender, data, this));
  321. }
  322. }
  323. public sealed class AnonymousEventData : IAnonymousEventData
  324. {
  325. public string EventName { get; }
  326. public string Hash { get; }
  327. internal AnonymousEventData(string eventName, string hash)
  328. {
  329. EventName = eventName;
  330. Hash = hash;
  331. }
  332. internal AnonymousEventData(string hash) : this(hash, hash)
  333. {
  334. }
  335. ConcurrentDictionary<Guid, ActionValue<object[]>> _list = new ConcurrentDictionary<Guid, ActionValue<object[]>>();
  336. public void Publish(object sender, Properties? properties, params object[] data)
  337. {
  338. properties ??= Properties.Default;
  339. if (_list.IsEmpty) return;
  340. var templist = _list.Where(x => x.Value.Properties.FilterRule(properties) && x.Value.HasDelegate).ToList();
  341. if (templist.Count == 0) return;
  342. foreach (var val in templist)
  343. {
  344. var args = new EventArgs<object[]>(data, Instance, val.Value.IntPtr,this);
  345. val.Value.Action.Invoke(sender, args);
  346. if (args.Handle) return;
  347. }
  348. }
  349. public void UnSubscrip(Guid guid)
  350. {
  351. if (guid == Guid.Empty) return;
  352. _list.TryRemove(guid, out _);
  353. }
  354. public Guid Subscrip(Action<object, EventArgs<object[]>> action, Properties? properties=null)
  355. {
  356. ArgumentNullException.ThrowIfNull(action);
  357. properties ??= Properties.Default;
  358. var act = new ActionValue<object[]>(action, properties);
  359. _list[act.IntPtr] = act;
  360. return act.IntPtr;
  361. }
  362. public void Clear() => _list.Clear();
  363. public async Task PublishAsync(object sender, Properties? properties = null, params object[] data)
  364. {
  365. properties ??= Properties.Default;
  366. if (_list.IsEmpty) return;
  367. var templist = _list.Where(x => x.Value.Properties.FilterRule(properties) && x.Value.HasDelegate).Select(x => x.Value).ToList();
  368. foreach (var val in templist)
  369. {
  370. var args = new EventArgs<object[]>(data, Instance, val.IntPtr, this);
  371. await System.Threading.Tasks.Task.Run(() => val.Action.Invoke(sender, args));
  372. if (args.Handle) return;
  373. }
  374. }
  375. }
  376. public sealed class AnonymousEventData<T> : IAnonymousEventData<T>
  377. {
  378. public string EventName { get; }
  379. public string Hash { get; }
  380. ConcurrentDictionary<Guid,BaseFuncValue<object[], T>> _list = new ConcurrentDictionary<Guid, BaseFuncValue<object[], T>>();
  381. internal AnonymousEventData(string eventName, string hash)
  382. {
  383. EventName = eventName;
  384. Hash = hash;
  385. }
  386. internal AnonymousEventData(string hash) : this(hash, hash)
  387. {
  388. }
  389. public T Publish(object sender, Properties? properties, params object[] data)
  390. {
  391. if (_list.IsEmpty) return Activator.CreateInstance<T>();
  392. properties ??= Properties.Default;
  393. 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();
  394. if (func.Count == 0) return Activator.CreateInstance<T>();
  395. return func.First().Invoke(sender, data, this);
  396. }
  397. public List<T> PublishList(object sender, Properties? properties, params object[] data)
  398. {
  399. if (_list.IsEmpty) return new List<T>();
  400. properties ??= Properties.Default;
  401. 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();
  402. if (func.Count == 0) return new List<T>();
  403. return func.First().InvokeList(sender, data, this);
  404. }
  405. public Guid Subscrip(Func<object, EventArgs<object[]>, T> func, Properties? properties=null)
  406. {
  407. ArgumentNullException.ThrowIfNull(func);
  408. properties ??= Properties.Default;
  409. var tempfunc = new FuncValue<object[], T>(func, properties);
  410. _list[tempfunc.IntPtr] = tempfunc;
  411. return tempfunc.IntPtr;
  412. }
  413. public Guid SubscripList(Func<object, EventArgs<object[]>, List<T>> func, Properties? properties=null)
  414. {
  415. ArgumentNullException.ThrowIfNull(func);
  416. properties ??= Properties.Default;
  417. var tempfunc = new ListFuncValue<object[], T>(func, properties);
  418. _list[tempfunc.IntPtr] = tempfunc;
  419. return tempfunc.IntPtr;
  420. }
  421. public void UnSubscrip(Guid guid)
  422. {
  423. if (guid == Guid.Empty) return;
  424. _list.TryRemove(guid, out _);
  425. }
  426. public void Clear()
  427. {
  428. _list.Clear();
  429. }
  430. public async Task<T> PublishAsync(object sender, Properties? properties = null, params object[] data)
  431. {
  432. if (_list.IsEmpty) return Activator.CreateInstance<T>();
  433. properties ??= Properties.Default;
  434. 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();
  435. if (func.Count == 0) return Activator.CreateInstance<T>();
  436. return await Task.Run(()=> func.First().Invoke(sender, data, this));
  437. }
  438. public async Task<List<T>> PublishListAsync(object sender, Properties? properties = null, params object[] data)
  439. {
  440. if (_list.IsEmpty) return new List<T>();
  441. properties ??= Properties.Default;
  442. 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();
  443. if (func.Count == 0) return new List<T>();
  444. return await Task.Run(()=> func.First().InvokeList(sender, data, this));
  445. }
  446. }
  447. private void Dispose(bool disposing)
  448. {
  449. if (!disposedValue)
  450. {
  451. if (disposing)
  452. {
  453. _list.Values.ToList().ForEach(x => x?.ToList().ForEach(y=>y.Clear()));
  454. _list.Clear();
  455. }
  456. // TODO: 释放未托管的资源(未托管的对象)并替代终结器
  457. // TODO: 将大型字段设置为 null
  458. disposedValue = true;
  459. }
  460. }
  461. // // TODO: 仅当“Dispose(bool disposing)”拥有用于释放未托管资源的代码时才替代终结器
  462. // ~EventBroker()
  463. // {
  464. // // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
  465. // Dispose(disposing: false);
  466. // }
  467. public void Dispose()
  468. {
  469. // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
  470. Dispose(disposing: true);
  471. GC.SuppressFinalize(this);
  472. }
  473. }
  474. }