/// <summary> /// Extract the <see cref="IHandlerRegistrar.RegisterHandler{TMessage}(System.Action{TMessage},System.Type,bool)"/> method of <see cref="GetEventHandlerRegistrar"/> or <see cref="GetCommandHandlerRegistrar"/>. /// Create an <see cref="Action"/> around the provided <paramref name="executorType"/> /// Then register the created <see cref="Action"/> using the extracted <see cref="IHandlerRegistrar.RegisterHandler{TMessage}(System.Action{TMessage},System.Type,bool)"/> method /// </summary> /// <param name="interface">The <see cref="Type"/> of <see cref="IHandler"/></param> /// <param name="trueForEventsFalseForCommands">Indicates if this is registers <see cref="IEventHandler"/> or <see cref="ICommandHandler{TAuthenticationToken,TCommand}"/>.</param> /// <param name="resolveMessageHandlerInterface"><see cref="ResolveEventHandlerInterface"/> or <see cref="ResolveCommandHandlerInterface"/></param> /// <param name="executorType">The <see cref="Type"/> of the event handler that will do the handling</param> protected virtual void InvokeHandler(Type @interface, bool trueForEventsFalseForCommands, Func <Type, IEnumerable <Type> > resolveMessageHandlerInterface, Type executorType) { MethodInfo registerExecutorMethod = null; MethodInfo originalRegisterExecutorMethod = (trueForEventsFalseForCommands ? GetEventHandlerRegistrar(null, executorType) : GetCommandHandlerRegistrar(null, executorType)) .GetType() .GetMethods(BindingFlags.Instance | BindingFlags.Public) .Where(mi => mi.Name == "RegisterHandler") .Where(mi => mi.IsGenericMethod) .Where(mi => mi.GetGenericArguments().Count() == 1) .Single(mi => mi.GetParameters().Count() == 3); IList <Type> interfaceGenericArguments = @interface.GetGenericArguments().ToList(); if (interfaceGenericArguments.Count == 2) { Type commandType = interfaceGenericArguments[1]; Type[] genericArguments = commandType.GetGenericArguments(); if (genericArguments.Length == 1) { if (typeof(IEvent <>).MakeGenericType(genericArguments.First()) == commandType) { return; } } registerExecutorMethod = BuildExecutorMethod(originalRegisterExecutorMethod, executorType, commandType); } else { foreach (Type commandType in interfaceGenericArguments) { try { registerExecutorMethod = BuildExecutorMethod(originalRegisterExecutorMethod, executorType, commandType); break; } catch (VerificationException) { } catch (ArgumentException) { } } } if (registerExecutorMethod == null) { throw new InvalidOperationException("No executor method could be compiled for " + @interface.FullName); } HandlerDelegate handlerDelegate = BuildDelegateAction(executorType, resolveMessageHandlerInterface); InvokeHandlerDelegate(registerExecutorMethod, trueForEventsFalseForCommands, handlerDelegate); }
/// <summary> /// Extract the <see cref="IHandlerRegistrar.RegisterHandler{TMessage}"/> method from the provided <paramref name="bus"/> /// Create an <see cref="Action"/> around the provided <paramref name="executorType"/> /// Then register the created <see cref="Action"/> using the extracted <see cref="IHandlerRegistrar.RegisterHandler{TMessage}"/> method /// </summary> /// <param name="executorType">The <see cref="Type"/> of the event handler that will do the handling</param> protected virtual void InvokeHandler(Type @interface, IHandlerRegistrar bus, Func <Type, IEnumerable <Type> > resolveMessageHandlerInterface, Type executorType) { MethodInfo registerExecutorMethod = null; MethodInfo originalRegisterExecutorMethod = bus .GetType() .GetMethods(BindingFlags.Instance | BindingFlags.Public) .Where(mi => mi.Name == "RegisterHandler") .Where(mi => mi.IsGenericMethod) .Where(mi => mi.GetGenericArguments().Count() == 1) .Single(mi => mi.GetParameters().Count() == 2); IList <Type> interfaceGenericArguments = @interface.GetGenericArguments().ToList(); if (interfaceGenericArguments.Count == 2) { Type commandType = interfaceGenericArguments[1]; registerExecutorMethod = BuildExecutorMethod(originalRegisterExecutorMethod, executorType, commandType); } else { foreach (Type commandType in interfaceGenericArguments) { try { registerExecutorMethod = BuildExecutorMethod(originalRegisterExecutorMethod, executorType, commandType); break; } catch (VerificationException) { } catch (ArgumentException) { } } } if (registerExecutorMethod == null) { throw new InvalidOperationException("No executor method could be compiled for " + @interface.FullName); } HandlerDelegate handlerDelegate = BuildDelegateAction(executorType, resolveMessageHandlerInterface); InvokeHandlerDelegate(registerExecutorMethod, bus, handlerDelegate); }
protected virtual void InvokeHandlerDelegate(MethodInfo registerExecutorMethod, IHandlerRegistrar bus, HandlerDelegate handlerDelegate) { registerExecutorMethod.Invoke(bus, new object[] { handlerDelegate.Delegate, handlerDelegate.TargetedType }); }
protected virtual void InvokeHandlerDelegate(MethodInfo registerExecutorMethod, IHandlerRegistrar bus, HandlerDelegate handlerDelegate) { bool holdMessageLock; try { string messageType = registerExecutorMethod.GetParameters()[0].ParameterType.GetGenericArguments()[0].FullName; string configuration = string.Format("{0}<{1}>.HoldMessageLock", handlerDelegate.TargetedType.FullName, messageType); // If this cannot be parsed then assume the safe route that this must be required to hold the lock. if (!bool.TryParse(DependencyResolver.Resolve <IConfigurationManager>().GetSetting(configuration), out holdMessageLock)) { holdMessageLock = true; } } catch { holdMessageLock = true; } registerExecutorMethod.Invoke(bus, new object[] { handlerDelegate.Delegate, handlerDelegate.TargetedType, holdMessageLock }); }