/TwinCat_Automation_Interface2/EventAggregator/EventAggregator.cs

https://gitlab.com/gnoel/TwinCat_Automation_Interface
C# | 138 lines | 81 code | 40 blank | 17 comment | 7 complexity | 87e5120020db1451f02e61f3e5f90d7e MD5 | raw file
  1. /*
  2. * Gautham Prabhu K 2014
  3. * Copyright (c) 2014 gautham.prabhu.se@gmail.com
  4. * All rights reserved.
  5. * No warranty of any kind implied or otherwise.
  6. *
  7. */
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Threading;
  13. namespace EventAggregator
  14. {
  15. public class EventAggregator : IEventAggregator
  16. {
  17. private Dictionary<Type, List<WeakReference>> eventSubsribers = new Dictionary<Type, List<WeakReference>>();
  18. private readonly object lockSubscriberDictionary = new object();
  19. #region IEventAggregator Members
  20. /// <summary>
  21. /// Publish an event
  22. /// </summary>
  23. /// <typeparam name="TEventType"></typeparam>
  24. /// <param name="eventToPublish"></param>
  25. public void PublishEvent<TEventType>(TEventType eventToPublish)
  26. {
  27. var subsriberType = typeof(ISubscriber<>).MakeGenericType(typeof(TEventType));
  28. var subscribers = GetSubscriberList(subsriberType);
  29. List<WeakReference> subsribersToBeRemoved = new List<WeakReference>();
  30. foreach (var weakSubsriber in subscribers)
  31. {
  32. if (weakSubsriber.IsAlive)
  33. {
  34. var subscriber = (ISubscriber<TEventType>)weakSubsriber.Target;
  35. InvokeSubscriberEvent<TEventType>(eventToPublish, subscriber);
  36. }
  37. else
  38. {
  39. subsribersToBeRemoved.Add(weakSubsriber);
  40. }//End-if-else (weakSubsriber.IsAlive)
  41. }//End-for-each (var weakSubriber in subscribers)
  42. if (subsribersToBeRemoved.Any())
  43. {
  44. lock (lockSubscriberDictionary)
  45. {
  46. foreach (var remove in subsribersToBeRemoved)
  47. {
  48. subscribers.Remove(remove);
  49. }//End-for-each (var remove in subsribersToBeRemoved)
  50. }//End-lock (lockSubscriberDictionary)
  51. }//End-if (subsribersToBeRemoved.Any())
  52. }
  53. /// <summary>
  54. /// Subribe to an event.
  55. /// </summary>
  56. /// <param name="subscriber"></param>
  57. public void SubsribeEvent(object subscriber)
  58. {
  59. lock (lockSubscriberDictionary)
  60. {
  61. var subsriberTypes = subscriber.GetType().GetInterfaces()
  62. .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ISubscriber<>));
  63. WeakReference weakReference = new WeakReference(subscriber);
  64. foreach (var subsriberType in subsriberTypes)
  65. {
  66. List<WeakReference> subscribers = GetSubscriberList(subsriberType);
  67. subscribers.Add(weakReference);
  68. }//End-for-each (var subsriberType in subsriberTypes)
  69. }//End-lock (lockSubscriberDictionary)
  70. }
  71. #endregion
  72. private void InvokeSubscriberEvent<TEventType>(TEventType eventToPublish, ISubscriber<TEventType> subscriber)
  73. {
  74. //Synchronize the invocation of method
  75. SynchronizationContext syncContext = SynchronizationContext.Current;
  76. if (syncContext == null)
  77. {
  78. syncContext = new SynchronizationContext();
  79. }//End-if (syncContext == null)
  80. syncContext.Post(s => subscriber.OnEventHandler(eventToPublish), null);
  81. }
  82. private List<WeakReference> GetSubscriberList(Type subsriberType)
  83. {
  84. List<WeakReference> subsribersList = null;
  85. lock (lockSubscriberDictionary)
  86. {
  87. bool found = this.eventSubsribers.TryGetValue(subsriberType, out subsribersList);
  88. if (!found)
  89. {
  90. //First time create the list.
  91. subsribersList = new List<WeakReference>();
  92. this.eventSubsribers.Add(subsriberType, subsribersList);
  93. }//End-if (!found)
  94. }//End-lock (lockSubscriberDictionary)
  95. return subsribersList;
  96. }
  97. }
  98. }