Пример #1
0
        // Helper to invoke any handler config attributes on this handler type or its base classes.
        private static void InvokeAttributesOnHandlerType(CommandHandlerDescriptor descriptor, Type type)
        {
            Contract.Requires(descriptor != null);

            if (type == null)
            {
                return;
            }

            // Initialize base class before derived classes (same order as ctors).
            InvokeAttributesOnHandlerType(descriptor, type.BaseType);

            // Check for attribute
            object[] attrs = type.GetCustomAttributes(inherit: false);
            for (int i = 0; i < attrs.Length; i++)
            {
                object attr = attrs[i];
                IHandlerConfiguration handlerConfig = attr as IHandlerConfiguration;
                if (handlerConfig != null)
                {
                    ProcessorConfiguration originalConfig = descriptor.Configuration;
                    CommandHandlerSettings settings       = new CommandHandlerSettings(originalConfig);
                    handlerConfig.Initialize(settings, descriptor);
                    descriptor.Configuration = ProcessorConfiguration.ApplyHandlerSettings(settings, originalConfig);
                }
            }
        }
Пример #2
0
        private static async Task <HandlerResponse> InvokeActionAsyncCore(CommandHandlerContext context, CancellationToken cancellationToken)
        {
            Contract.Requires(context != null);
            Contract.Requires(context.Descriptor != null);

            CommandHandlerDescriptor handlerDescriptor = context.Descriptor;

            try
            {
                object result = await handlerDescriptor.ExecuteAsync(context, cancellationToken);

                // This is cached in a local for performance reasons. ReturnType is a virtual property on CommandHandlerDescriptor,
                // or else we'd want to cache this as part of that class.
                bool isDeclaredTypeHandlerResult = typeof(ICommandHandlerResult).IsAssignableFrom(handlerDescriptor.ReturnType);
                if (result == null && isDeclaredTypeHandlerResult)
                {
                    // If the return type of the action descriptor is IHandlerResult, it's not valid to return null
                    throw Error.InvalidOperation(Resources.DefaultHandlerInvoker_NullHandlerResult);
                }

                if (isDeclaredTypeHandlerResult || handlerDescriptor.ReturnType == typeof(object))
                {
                    ICommandHandlerResult actionResult = result as ICommandHandlerResult;

                    if (actionResult == null && isDeclaredTypeHandlerResult)
                    {
                        // If the return type of the action descriptor is IHandlerResult, it's not valid to return an
                        // object that doesn't implement IHandlerResult
                        throw Error.InvalidOperation(Resources.DefaultHandlerInvoker_InvalidHandlerResult, result.GetType());
                    }

                    if (actionResult != null)
                    {
                        HandlerResponse response = await actionResult.ExecuteAsync(cancellationToken);

                        if (response == null)
                        {
                            throw Error.InvalidOperation(Resources.DefaultHandlerInvoker_NullHandlerResponse);
                        }

                        HandlerResponse.EnsureResponseHasRequest(response, context.Request);
                        return(response);
                    }
                }

                // This is a non-IHandlerResult, so run the converter
                return(handlerDescriptor.ResultConverter.Convert(context, result));
            }
            catch (HandlerResponseException handlerResponseException)
            {
                HandlerResponse response = handlerResponseException.Response;
                HandlerResponse.EnsureResponseHasRequest(response, context.Request);

                return(response);
            }
        }
Пример #3
0
        /// <summary>
        /// Execute the request via the worker.
        /// </summary>
        /// <param name="request">The <see cref="HandlerRequest"/> to execute.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> to cancel the execution.</param>
        /// <returns>The result of the command, if any.</returns>
        public Task <HandlerResponse> ExecuteAsync(CommandHandlerRequest request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            cancellationToken.ThrowIfCancellationRequested();
            ServicesContainer        servicesContainer = request.Configuration.Services;
            ICommandHandlerSelector  handlerSelector   = servicesContainer.GetHandlerSelector();
            CommandHandlerDescriptor descriptor        = handlerSelector.SelectHandler(request);

            ICommandHandler commandHandler = descriptor.CreateHandler(request);

            if (commandHandler == null)
            {
                throw CreateHandlerNotFoundException(descriptor);
            }

            request.RegisterForDispose(commandHandler, true);
            CommandHandlerContext context = new CommandHandlerContext(request, descriptor);

            context.Handler = commandHandler;
            commandHandler.CommandContext = context;

            CommandFilterGrouping commandFilterGrouping = descriptor.GetFilterGrouping();

            ICommandHandlerResult result = new CommandHandlerFilterResult(context, servicesContainer, commandFilterGrouping.CommandHandlerFilters);

            if (descriptor.RetryPolicy != RetryPolicy.NoRetry)
            {
                result = new RetryHandlerResult(descriptor.RetryPolicy, result);
            }

            if (commandFilterGrouping.ExceptionFilters.Length > 0)
            {
                IExceptionLogger  exceptionLogger  = ExceptionServices.GetLogger(servicesContainer);
                IExceptionHandler exceptionHandler = ExceptionServices.GetHandler(servicesContainer);
                result = new ExceptionFilterResult(context, commandFilterGrouping.ExceptionFilters, exceptionLogger, exceptionHandler, result);
            }

            return(result.ExecuteAsync(cancellationToken));
        }
Пример #4
0
        private static CommandHandlerNotFoundException CreateHandlerNotFoundException(CommandHandlerDescriptor descriptor)
        {
            Contract.Requires(descriptor != null);

            if (descriptor.ReturnType == typeof(VoidResult))
            {
                return(new CommandHandlerNotFoundException(descriptor.MessageType));
            }

            return(new CommandHandlerNotFoundException(descriptor.MessageType, descriptor.ReturnType));
        }