public EventDispatcher(EventConfigSection eventConfigSection, Func <Type, object> resolver = null) { if (eventConfigSection == null) { throw new ArgumentNullException(nameof(eventConfigSection)); } LoadFromConfig(eventConfigSection, resolver); Log.Info($"Loaded definitions of {_hooks.Count} hooks, {_hooks.Count(h=>h.CreatedSucessfully)} have been created sucessfully."); }
private void LoadFromConfig([NotNull] EventConfigSection eventConfigSection, Func <Type, object> resolver) { // Passed resolver renders defined locator obsolete if (resolver == null) { resolver = GetResolverFromDefinedLocator(eventConfigSection); } foreach (var eventConfig in eventConfigSection.Events) { try { // Check if there is a point to even loading this one if (eventConfig.Consumers.Count == 0) { Log.Warn($"Event {eventConfig.Producer.QualifiedClassName}.{eventConfig.Producer.EventName} has no defined consumers. Skipping..."); continue; } var(eventInfo, producerInstance) = LoadProducer(eventConfig.Producer, resolver, eventConfigSection.ThrowOnErrors); if (eventInfo == null) { continue; // the event was not loaded correctly and exception was NOT thrown } // we have instance (or not), event (static or not, doesn't matter). We can now start iterating consumers foreach (var consumer in eventConfig.Consumers) { var(methodInfo, consumerInstance) = LoadConsumer(consumer, resolver, eventConfigSection.ThrowOnErrors); if (methodInfo == null) { continue; // we were unable to load consumer AND exception was not thrown } // we good. We can create our hook _hooks.Add(new DelegatingHook(eventInfo, producerInstance, methodInfo, consumerInstance, eventConfigSection.ThrowOnErrors)); } } catch (Exception exception) { var message = $"Error while processing {eventConfig.Producer.QualifiedClassName}.{eventConfig.Producer.EventName} event."; Log.Error(exception, message); if (eventConfigSection.ThrowOnErrors) { throw new EventDispatcherException(message, exception); } } } }
private static Func <Type, object> GetResolverFromDefinedLocator(EventConfigSection eventConfigSection) { Func <Type, object> resolver = null; if (eventConfigSection.Locator != null) { var locatorType = Type.GetType(eventConfigSection.Locator.QualifiedClassName, false); if (locatorType != null) { var locator = locatorType.GetMethod(eventConfigSection.Locator.MethodName, BindingFlags.Public | BindingFlags.Static); if (locator == null) { var message = $"Cannot find {nameof(EventConfigSection.Locator)} method {eventConfigSection.Locator.MethodName}"; Log.Warn(message); if (eventConfigSection.ThrowOnErrors) { throw new EventDispatcherException(message); } } else { // Here we have a locator - some static method of some class that should turn Type into object (of that type) // Let's check if we really do var parameters = locator.GetParameters(); if (locator.ReturnType == typeof(object) && parameters.Length == 1 && parameters.Single().ParameterType == typeof(Type)) { // Ok, this will work resolver = Expression .Lambda <Func <Type, object> >(Expression.Call(locator, Expression.Parameter(typeof(Type), "type"))).Compile(); } else { var message = $"Cannot use {eventConfigSection.Locator.QualifiedClassName}.{eventConfigSection.Locator.MethodName} as {nameof(EventConfigSection.Locator)} as it is not a f(Type)=>object method"; if (eventConfigSection.ThrowOnErrors) { throw new EventDispatcherException(message); } } } } else { var message = $"Cannot load {nameof(EventConfigSection.Locator)} type {eventConfigSection.Locator.QualifiedClassName}"; Log.Warn(message); if (eventConfigSection.ThrowOnErrors) { throw new EventDispatcherException(message); } } } return(resolver); }