// 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); } } }
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); } }
/// <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)); }
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)); }