PageRenderTime 25ms CodeModel.GetById 8ms RepoModel.GetById 1ms app.codeStats 0ms

/MVCForum.Core/Events/EventManager.cs

http://themvcforum.codeplex.com
C# | 290 lines | 218 code | 48 blank | 24 comment | 36 complexity | 5df0b37ac10c746fe1594411c32a08c1 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, BSD-3-Clause, GPL-2.0
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Reflection;
  5. using MVCForum.Domain.Interfaces.API;
  6. using MVCForum.Domain.Interfaces.Events;
  7. using MVCForum.Domain.Interfaces.Services;
  8. using MVCForum.Utilities;
  9. namespace MVCForum.Domain.Events
  10. {
  11. public sealed class EventManager : IEventManager
  12. {
  13. private const string InterfaceTargetName =@"MVCForum.Domain.Interfaces.Events.IEventHandler";
  14. public EventHandler<BadgeEventArgs> BeforeBadgeAwarded;
  15. public EventHandler<VoteEventArgs> BeforeVoteMade;
  16. public EventHandler<MarkedAsSolutionEventArgs> BeforeMarkedAsSolution;
  17. public EventHandler<PostMadeEventArgs> BeforePostMade;
  18. public EventHandler<RegisterUserEventArgs> BeforeRegisterUser;
  19. public EventHandler<UpdateProfileEventArgs> BeforeUpdateProfile;
  20. public EventHandler<BadgeEventArgs> AfterBadgeAwarded;
  21. public EventHandler<VoteEventArgs> AfterVoteMade;
  22. public EventHandler<MarkedAsSolutionEventArgs> AfterMarkedAsSolution;
  23. public EventHandler<PostMadeEventArgs> AfterPostMade;
  24. public EventHandler<RegisterUserEventArgs> AfterRegisterUser;
  25. public EventHandler<UpdateProfileEventArgs> AfterUpdateProfile;
  26. private static volatile EventManager _instance;
  27. private static readonly object SyncRoot = new Object();
  28. public ILoggingService Logger { get; set; }
  29. /// <summary>
  30. /// Constructor - hidden
  31. /// </summary>
  32. private EventManager()
  33. {
  34. }
  35. /// <summary>
  36. /// Callback used when comparing objects to see if they implement an interface
  37. /// </summary>
  38. /// <param name="typeObj"></param>
  39. /// <param name="criteriaObj"></param>
  40. /// <returns></returns>
  41. private static bool InterfaceFilter(Type typeObj, Object criteriaObj)
  42. {
  43. return typeObj.ToString() == criteriaObj.ToString();
  44. }
  45. /// <summary>
  46. /// Singleton instance
  47. /// </summary>
  48. public static EventManager Instance
  49. {
  50. get
  51. {
  52. if (_instance == null)
  53. {
  54. lock (SyncRoot)
  55. {
  56. if (_instance == null)
  57. {
  58. _instance = new EventManager();
  59. }
  60. }
  61. }
  62. return _instance;
  63. }
  64. }
  65. /// <summary>
  66. /// Use reflection to get all event handling classes. Call this ONCE.
  67. /// </summary>
  68. public void Initialize(ILoggingService loggingService)
  69. {
  70. Logger = loggingService;
  71. var interfaceFilter = new TypeFilter(InterfaceFilter);
  72. var path = AppDomain.CurrentDomain.RelativeSearchPath;
  73. // Get all the dlls
  74. var di = new DirectoryInfo(path);
  75. foreach (var file in di.GetFiles("*.dll"))
  76. {
  77. if (file.Name.ToLower().StartsWith("ecmascript"))
  78. {
  79. continue;
  80. }
  81. Assembly nextAssembly;
  82. try
  83. {
  84. nextAssembly = Assembly.LoadFrom(file.FullName);
  85. }
  86. catch (BadImageFormatException)
  87. {
  88. // Not an assembly ignore
  89. continue;
  90. }
  91. if (nextAssembly.FullName.StartsWith("System") || nextAssembly.FullName.StartsWith("Microsoft"))
  92. {
  93. // Skip microsoft assemblies
  94. continue;
  95. }
  96. try
  97. {
  98. foreach (var type in nextAssembly.GetTypes())
  99. {
  100. if (type.IsInterface)
  101. {
  102. continue;
  103. }
  104. var myInterfaces = type.FindInterfaces(interfaceFilter, InterfaceTargetName);
  105. if (myInterfaces.Length <= 0)
  106. {
  107. // Not a match
  108. continue;
  109. }
  110. var ctor = type.GetConstructors().First();
  111. var createdActivator = ReflectionUtilities.GetActivator<IEventHandler>(ctor);
  112. // Create an instance:
  113. var instance = createdActivator();
  114. instance.RegisterHandlers(this);
  115. }
  116. }
  117. catch (ReflectionTypeLoadException rtle)
  118. {
  119. var msg =
  120. string.Format(
  121. "Unable to load assembly. Probably not an event assembly. In file named '{0}', loader exception was: '{1}':'{2}'.",
  122. file.Name, rtle.LoaderExceptions[0].GetType(), rtle.LoaderExceptions[0].Message);
  123. LogError(msg);
  124. }
  125. catch (Exception ex)
  126. {
  127. LogError(string.Format("Error reflecting over event handlers: {0}", ex.Message));
  128. }
  129. }
  130. }
  131. /// <summary>
  132. /// Log errors
  133. /// </summary>
  134. /// <param name="msg"></param>
  135. public void LogError(string msg)
  136. {
  137. if (Logger != null)
  138. {
  139. Logger.Error(msg);
  140. }
  141. }
  142. #region Event triggers
  143. public void FireAfterBadgeAwarded(object sender, BadgeEventArgs eventArgs)
  144. {
  145. var handler = AfterBadgeAwarded;
  146. if (handler != null)
  147. {
  148. handler(this, eventArgs);
  149. }
  150. }
  151. public void FireBeforeBadgeAwarded(object sender, BadgeEventArgs eventArgs)
  152. {
  153. var handler = BeforeBadgeAwarded;
  154. if (handler != null)
  155. {
  156. handler(this, eventArgs);
  157. }
  158. }
  159. public void FireBeforeVoteMade(object sender, VoteEventArgs eventArgs)
  160. {
  161. var handler = BeforeVoteMade;
  162. if (handler != null)
  163. {
  164. handler(this, eventArgs);
  165. }
  166. }
  167. public void FireBeforeMarkedAsSolution(object sender, MarkedAsSolutionEventArgs eventArgs)
  168. {
  169. var handler = BeforeMarkedAsSolution;
  170. if (handler != null)
  171. {
  172. handler(this, eventArgs);
  173. }
  174. }
  175. public void FireBeforePostMade(object sender, PostMadeEventArgs eventArgs)
  176. {
  177. var handler = BeforePostMade;
  178. if (handler != null)
  179. {
  180. handler(this, eventArgs);
  181. }
  182. }
  183. public void FireBeforeRegisterUser(object sender, RegisterUserEventArgs eventArgs)
  184. {
  185. var handler = BeforeRegisterUser;
  186. if (handler != null)
  187. {
  188. handler(this, eventArgs);
  189. }
  190. }
  191. public void FireBeforeProfileUpdated(object sender, UpdateProfileEventArgs eventArgs)
  192. {
  193. var handler = BeforeUpdateProfile;
  194. if (handler != null)
  195. {
  196. handler(this, eventArgs);
  197. }
  198. }
  199. public void FireAfterVoteMade(object sender, VoteEventArgs eventArgs)
  200. {
  201. var handler = AfterVoteMade;
  202. if (handler != null)
  203. {
  204. handler(this, eventArgs);
  205. }
  206. }
  207. public void FireAfterMarkedAsSolution(object sender, MarkedAsSolutionEventArgs eventArgs)
  208. {
  209. var handler = AfterMarkedAsSolution;
  210. if (handler != null)
  211. {
  212. handler(this, eventArgs);
  213. }
  214. }
  215. public void FireAfterPostMade(object sender, PostMadeEventArgs eventArgs)
  216. {
  217. var handler = AfterPostMade;
  218. if (handler != null)
  219. {
  220. handler(this, eventArgs);
  221. }
  222. }
  223. public void FireAfterRegisterUser(object sender, RegisterUserEventArgs eventArgs)
  224. {
  225. var handler = AfterRegisterUser;
  226. if (handler != null)
  227. {
  228. handler(this, eventArgs);
  229. }
  230. }
  231. public void FireAfterProfileUpdated(object sender, UpdateProfileEventArgs eventArgs)
  232. {
  233. var handler = AfterUpdateProfile;
  234. if (handler != null)
  235. {
  236. handler(this, eventArgs);
  237. }
  238. }
  239. #endregion
  240. public IMVCForumAPI API { get; set; }
  241. }
  242. }