Ejemplo n.º 1
0
        /// <summary>
        /// Builds an <see cref="IEventHandler{TEventType}"/> from <typeparamref name="THandlerType"/> using a <see cref="FactoryFor{T}"/> to invoke the handler methods.
        /// </summary>
        /// <typeparam name="THandlerType">The type of the event handler to build for.</typeparam>
        /// <param name="factory">The <see cref="FactoryFor{T}"/> that will be used to instantiate the event handler.</param>
        /// <returns>A <see cref="IEventHandler{TEventType}"/> that can be registered with an <see cref="IRegisterEventHandlers"/>.</returns>
        public static IEventHandler <TEventType> BuildFor <THandlerType>(FactoryFor <THandlerType> factory)
        {
            var builder     = EventHandlerBuilder.Create <TEventType>().With(factory);
            var handlerType = typeof(THandlerType);

            foreach (var method in handlerType.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
            {
                ThrowIfMethodHasCorrectSignatureButWrongName(method);

                if (method.Name == HandleMethodName)
                {
                    ThrowIfFirstMethodParameterIsNot <TEventType>(method);
                    ThrowIfSecondMethodParameterIsNotEventContext(method);
                    ThrowIfMethodHasExtraParameters(method);
                    ThrowIfMethodDoesNotReturnATask(method);

                    TryGetFirstMethodParameter <TEventType>(method, out var eventType);
                    var delegateType        = typeof(EventHandlerMethod <,>).MakeGenericType(handlerType, eventType);
                    var dynamicDelegate     = method.CreateDelegate(delegateType, null);
                    var builderHandleMethod = typeof(EventHandlerFactoryBuilder <THandlerType, TEventType>).GetMethod(nameof(EventHandlerFactoryBuilder <THandlerType, TEventType> .Handle));
                    var dynamicHandleMethod = builderHandleMethod.MakeGenericMethod(eventType);
                    dynamicHandleMethod.Invoke(builder, new[] {  dynamicDelegate });
                }
            }

            return(builder.Build());
        }