public void WhenDisposingScopeFromDeepestRequestThenScopesAreDisposed() { // Arrange Mock <ICommand> command = new Mock <ICommand>(); HandlerRequest request = new CommandHandlerRequest(this.defaultConfig, command.Object); HandlerRequest innerRequest = new CommandHandlerRequest(this.defaultConfig, command.Object, request); Mock <IDependencyResolver> resolver = new Mock <IDependencyResolver>(MockBehavior.Strict); int disposedCount = 0; resolver .Setup(r => r.BeginScope()) .Returns(() => CreateVerifiableScopeMock(() => disposedCount++)); resolver .Setup(r => r.Dispose()); this.defaultConfig.DependencyResolver = resolver.Object; request.GetDependencyScope(); innerRequest.GetDependencyScope(false); // Act & Assert Assert.Equal(0, disposedCount); innerRequest.Dispose(); Assert.Equal(1, disposedCount); request.Dispose(); Assert.Equal(2, disposedCount); }
/// <summary> /// Attaches the given <paramref name="request"/> to the <paramref name="response"/> if the response does not already /// have a pointer to a request. /// </summary> /// <param name="response">The response.</param> /// <param name="request">The request.</param> public static void EnsureResponseHasRequest(HandlerResponse response, CommandHandlerRequest request) { if (response != null && response.Request == null) { response.Request = request; } }
/// <inheritdocs /> public async Task <HandlerResponse> ExecuteAsync(CommandHandlerRequest request, CancellationToken cancellationToken) { ICommandSender sender = request.Configuration.Services.GetCommandSender(); await sender.SendAsync(request.Command, cancellationToken); return(new HandlerResponse(request)); }
public void CreateTranscientHandler_InstancianteEachTime() { // Arrange var config = new ProcessorConfiguration(); config.DefaultHandlerLifetime = HandlerLifetime.Transient; ICommandHandlerActivator activator = new DefaultCommandHandlerActivator(); CommandHandlerRequest request1 = new CommandHandlerRequest(config, this.command.Object); CommandHandlerRequest request2 = new CommandHandlerRequest(config, this.command.Object); CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(config, typeof(SimpleCommand), typeof(SimpleCommandHandler)); CommandHandlerDescriptor descriptor2 = new CommandHandlerDescriptor(config, typeof(SimpleCommand), typeof(SimpleCommandHandler)); // Act var handler1 = activator.Create(request1, descriptor); var handler2 = activator.Create(request1, descriptor); var handler3 = activator.Create(request2, descriptor); var handler4 = activator.Create(request1, descriptor2); // Assert Assert.NotNull(handler1); Assert.NotNull(handler2); Assert.NotNull(handler3); Assert.NotNull(handler4); Assert.NotSame(handler1, handler2); Assert.NotSame(handler1, handler3); Assert.NotSame(handler1, handler4); Assert.NotSame(handler2, handler3); Assert.NotSame(handler2, handler4); Assert.NotSame(handler3, handler4); }
public void WhenGettingDependencyScopeThenDelegatesToDependencyResolver() { // Arrange Mock <ICommand> command = new Mock <ICommand>(); HandlerRequest request = new CommandHandlerRequest(this.defaultConfig, command.Object); Mock <IDependencyScope> scope = new Mock <IDependencyScope>(MockBehavior.Strict); scope.Setup(s => s.Dispose()); Mock <IDependencyResolver> resolver = new Mock <IDependencyResolver>(MockBehavior.Strict); resolver .Setup(r => r.BeginScope()) .Returns(scope.Object); resolver .Setup(r => r.Dispose()); this.defaultConfig.DependencyResolver = resolver.Object; // Act var scope1 = request.GetDependencyScope(); var scope2 = request.GetDependencyScope(); // Assert Assert.NotNull(scope1); Assert.Same(scope1, scope2); resolver.Verify(r => r.BeginScope(), Times.Once()); }
public void WhenCreatingHandlerFromTwoDescriptorsAndDependencyResolverThenGetActivatorDepencyResolver() { // Assign ICommandHandlerActivator activator = new DefaultCommandHandlerActivator(); CommandHandlerRequest request = new CommandHandlerRequest(this.config, this.command.Object); CommandHandlerDescriptor descriptor1 = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler)); CommandHandlerDescriptor descriptor2 = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler)); int[] i = { 0 }; this.dependencyResolver .When(() => i[0] < 1) .Setup(resolver => resolver.GetService(typeof(SimpleCommandHandler))) .Returns(null) .Callback(() => i[0]++); this.dependencyResolver .When(() => i[0] >= 1) .Setup(resolver => resolver.GetService(typeof(SimpleCommandHandler))) .Returns(new SimpleCommandHandler()); // Act activator.Create(request, descriptor1); ICommandHandler commandHandler = activator.Create(request, descriptor2); // Assert Assert.NotNull(commandHandler); Assert.IsType(typeof(SimpleCommandHandler), commandHandler); Assert.Equal(0, descriptor2.Properties.Count); this.dependencyResolver.Verify(resolver => resolver.GetService(typeof(SimpleCommandHandler)), Times.Exactly(2)); }
public void WhenCreatingHandlerThrowExceptionThenRethowsInvalidOperationException() { // Arrange ICommandHandlerActivator activator = new DefaultCommandHandlerActivator(); CommandHandlerRequest request = new CommandHandlerRequest(this.config, this.command.Object); CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler)); this.dependencyResolver .Setup(resolver => resolver.GetService(typeof(SimpleCommandHandler))) .Throws <CommandHandlerNotFoundException>(); bool exceptionRaised = false; // Act try { activator.Create(request, descriptor); } catch (InvalidOperationException) { exceptionRaised = true; } // Assert Assert.True(exceptionRaised); }
/// <summary> /// Determines whether the command is valid and adds any validation errors to the command's ValidationResults. /// </summary> /// <param name="request">The <see cref="HandlerRequest"/> to be validated.</param> /// <returns>true if command is valid, false otherwise.</returns> public bool Validate(CommandHandlerRequest request) { if (request == null) { throw Error.ArgumentNull("request"); } ModelValidatorProvider[] validatorProviders = request.Configuration.Services.GetModelValidatorProviders(); // Optimization : avoid validating the object graph if there are no validator providers if (validatorProviders.Length == 0) { return(true); } ModelMetadataProvider metadataProvider = request.Configuration.Services.GetModelMetadataProvider(); ModelMetadata metadata = metadataProvider.GetMetadataForType(() => request.Command, request.MessageType); ValidationContext validationContext = new ValidationContext { MetadataProvider = metadataProvider, ValidatorProviders = validatorProviders, ValidatorCache = request.Configuration.Services.GetModelValidatorCache(), ModelState = request.ModelState, Visited = new HashSet <object>(ReferenceEqualityComparer.Instance), KeyBuilders = new Stack <IKeyBuilder>(), RootPrefix = string.Empty }; return(this.ValidateNodeAndChildren(metadata, validationContext, container: null)); }
/// <summary> /// Initializes a new instance of the <see cref="ExceptionContext"/> class using the values provided. /// </summary> /// <param name="exceptionInfo">The exception caught.</param> /// <param name="catchBlock">The catch block where the exception was caught.</param> /// <param name="context">The context in which the exception occurred.</param> public ExceptionContext(ExceptionDispatchInfo exceptionInfo, ExceptionContextCatchBlock catchBlock, CommandHandlerContext context) { if (exceptionInfo == null) { throw new ArgumentNullException("exceptionInfo"); } this.ExceptionInfo = exceptionInfo; if (catchBlock == null) { throw new ArgumentNullException("catchBlock"); } this.CatchBlock = catchBlock; if (context == null) { throw new ArgumentNullException("context"); } this.Context = context; CommandHandlerRequest request = context.Request; if (request == null) { throw Error.ArgumentNull(Resources.TypePropertyMustNotBeNull, typeof(HandlerRequest).Name, "Request", "context"); } this.Request = request; }
public override ICommandHandler CreateHandler(CommandHandlerRequest request) { ICommandHandler commandHandler = null; this.traceWriter.TraceBeginEnd( request, TraceCategories.HandlersCategory, TraceLevel.Info, this.innerDescriptor.GetType().Name, CreateHandlerMethodName, beginTrace: null, execute: () => { commandHandler = this.innerDescriptor.CreateHandler(request); }, endTrace: tr => tr.Message = commandHandler == null ? Resources.TraceNoneObjectMessage : this.innerDescriptor.HandlerType.FullName, errorTrace: null); if (commandHandler != null && !(commandHandler is CommandHandlerTracer)) { return(new CommandHandlerTracer(request, commandHandler, this.traceWriter)); } return(commandHandler); }
private static ICommandHandlerResult CreateDefaultLastChanceResult(ExceptionContext context) { Contract.Requires(context != null); if (context.ExceptionInfo == null) { return(null); } Exception exception = context.ExceptionInfo.SourceException; CommandHandlerRequest request = context.Request; if (request == null) { return(null); } ProcessorConfiguration configuration = request.Configuration; if (configuration == null) { return(null); } ServicesContainer services = configuration.Services; Contract.Assert(services != null); return(new ExceptionResult(exception, request)); }
public void WhenGettingDependencyScopeFromDeepestRequestThenDelegatesToDeepestDependencyResolver() { // Arrange Mock <ICommand> command = new Mock <ICommand>(); HandlerRequest request = new CommandHandlerRequest(this.defaultConfig, command.Object); HandlerRequest innerRequest = new CommandHandlerRequest(this.defaultConfig, command.Object, request); Mock <IDependencyResolver> resolver = new Mock <IDependencyResolver>(MockBehavior.Strict); resolver .Setup(r => r.BeginScope()) .Returns(CreateScopeMock); resolver .Setup(r => r.Dispose()); this.defaultConfig.DependencyResolver = resolver.Object; // Act var scope1 = request.GetDependencyScope(); var scope2 = request.GetDependencyScope(false); var scope3 = innerRequest.GetDependencyScope(); var scope4 = innerRequest.GetDependencyScope(false); // Assert Assert.NotNull(scope1); Assert.NotNull(scope2); Assert.NotNull(scope3); Assert.NotNull(scope4); Assert.Same(scope1, scope2); Assert.Same(scope1, scope3); Assert.NotSame(scope1, scope4); resolver.Verify(r => r.BeginScope(), Times.Exactly(2)); }
public void WhenDisposingThenScopeIsDisposed() { // Arrange Mock <ICommand> command = new Mock <ICommand>(); HandlerRequest request = new CommandHandlerRequest(this.defaultConfig, command.Object); Mock <IDependencyScope> scope = new Mock <IDependencyScope>(MockBehavior.Strict); scope.Setup(s => s.Dispose()); Mock <IDependencyResolver> resolver = new Mock <IDependencyResolver>(MockBehavior.Strict); resolver .Setup(r => r.BeginScope()) .Returns(scope.Object); resolver .Setup(r => r.Dispose()); this.defaultConfig.DependencyResolver = resolver.Object; request.GetDependencyScope(); // Act request.Dispose(); // Assert scope.Verify(s => s.Dispose(), Times.Once()); }
CommandHandlerDescriptor ICommandHandlerSelector.SelectHandler(CommandHandlerRequest request) { CommandHandlerDescriptor handlerDescriptor = null; this.traceWriter.TraceBeginEnd( request, TraceCategories.HandlersCategory, TraceLevel.Info, this.innerSelector.GetType().Name, SelectActionMethodName, beginTrace: null, execute: () => handlerDescriptor = this.innerSelector.SelectHandler(request), endTrace: tr => { tr.Message = Error.Format( Resources.TraceHandlerSelectedMessage, FormattingUtilities.HandlerDescriptorToString(handlerDescriptor)); }, errorTrace: null); // Intercept returned HttpActionDescriptor with a tracing version if (handlerDescriptor != null && !(handlerDescriptor is CommandHandlerDescriptorTracer)) { return(new CommandHandlerDescriptorTracer(handlerDescriptor, this.traceWriter)); } return(handlerDescriptor); }
/// <summary> /// Process the command. /// </summary> /// <param name="command">The command to process.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param> /// <param name="currentRequest">The current request. Pass null if there is not parent request.</param> /// <returns>The result of the command.</returns> internal async Task <HandlerResponse> ProcessAsync(ICommand command, CancellationToken cancellationToken, HandlerRequest currentRequest) { if (command == null) { throw Error.ArgumentNull("command"); } if (this.disposed) { throw new ObjectDisposedException(this.GetType().FullName); } this.EnsureInitialized(); using (CommandHandlerRequest request = new CommandHandlerRequest(this.Configuration, command, currentRequest)) { request.Processor = new MessageProcessorWrapper(this, request); ExceptionDispatchInfo exceptionInfo; try { if (!ValidateCommand(request) && request.Configuration.AbortOnInvalidCommand) { HandlerResponse reponse = new HandlerResponse(request); return(reponse); } ICommandWorker commandWorker = this.Configuration.Services.GetCommandWorker(); return(await commandWorker.ExecuteAsync(request, cancellationToken)); } catch (OperationCanceledException) { // Propogate the canceled task without calling exception loggers or handlers. throw; } catch (HandlerResponseException exception) { return(exception.Response); } catch (Exception exception) { exceptionInfo = ExceptionDispatchInfo.Capture(exception); } ExceptionContext exceptionContext = new ExceptionContext(exceptionInfo, ExceptionCatchBlocks.MessageProcessor, request); await this.ExceptionLogger.LogAsync(exceptionContext, cancellationToken); HandlerResponse response = await this.ExceptionHandler.HandleAsync(exceptionContext, cancellationToken); if (response == null) { exceptionInfo.Throw(); } return(response); } }
public void WhenSelectingBadHandlerThenThrowsInvalidOperationException() { // Assign DefaultCommandHandlerSelector resolver = this.CreateTestableService(); CommandHandlerRequest request = new CommandHandlerRequest(this.config, new BadCommand()); // Act & assert Assert.Throws <InvalidOperationException>(() => resolver.SelectHandler(request)); }
public void WhenExecutedFilterVaryByUserThenCacheIsUpdated() { // Arrange CacheAttribute filter = this.CreateAttribute(new MemoryCache("test")); filter.Duration = 10; filter.VaryByUser = true; filter.VaryByParams = CacheAttribute.VaryByParamsNone; CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler)); SimpleCommand command1 = new SimpleCommand { Property1 = 1, Property2 = "test1" }; CommandHandlerRequest request1 = new CommandHandlerRequest(this.config, command1); CommandHandlerContext context1 = new CommandHandlerContext(request1, descriptor); context1.User = new GenericPrincipal(new GenericIdentity("user1"), null); CommandHandlerExecutedContext executedContext1 = new CommandHandlerExecutedContext(context1, null); executedContext1.Response = new HandlerResponse(request1, "result1"); SimpleCommand command2 = new SimpleCommand { Property1 = 1, Property2 = "test1" }; CommandHandlerRequest request2 = new CommandHandlerRequest(this.config, command2); CommandHandlerContext context2 = new CommandHandlerContext(request2, descriptor); context2.User = new GenericPrincipal(new GenericIdentity("user2"), null); CommandHandlerExecutedContext executedContext2 = new CommandHandlerExecutedContext(context2, null); executedContext2.Response = new HandlerResponse(request2, "result2"); SimpleCommand command3 = new SimpleCommand { Property1 = 1, Property2 = "test1" }; CommandHandlerRequest request3 = new CommandHandlerRequest(this.config, command3); CommandHandlerContext context3 = new CommandHandlerContext(request3, descriptor); context3.User = new GenericPrincipal(new GenericIdentity("user1"), null); CommandHandlerExecutedContext executedContext3 = new CommandHandlerExecutedContext(context3, null); executedContext3.Response = new HandlerResponse(request3, "result3"); // Act filter.OnCommandExecuting(context1); filter.OnCommandExecuted(executedContext1); filter.OnCommandExecuting(context2); filter.OnCommandExecuted(executedContext2); filter.OnCommandExecuting(context3); filter.OnCommandExecuted(executedContext3); // Assert Assert.Equal("result1", executedContext1.Response.Value); Assert.Equal("result2", executedContext2.Response.Value); Assert.Equal("result1", executedContext3.Response.Value); }
/// <summary>Initializes a new instance of the <see cref="ExceptionResult"/> class.</summary> /// <param name="exception">The exception to include in the error.</param> /// <param name="request">The request message which led to this result.</param> public ExceptionResult(Exception exception, CommandHandlerRequest request) { if (exception == null) { throw new ArgumentNullException("exception"); } this.Exception = exception; this.Request = request; }
public void WhenSelectingDuplicateHandlerThenThrowsInvalidOperationException() { // Assign DefaultCommandHandlerSelector resolver = this.CreateTestableService(); CommandHandlerRequest request = new CommandHandlerRequest(this.config, new SimpleCommand()); this.config.Services.Replace(typeof(ICommandHandlerTypeResolver), new DuplicateCommandHandlerTypeResolver()); // Act & assert Assert.Throws <InvalidOperationException>(() => resolver.SelectHandler(request)); }
/// <inheritsdoc /> public async Task <HandlerResponse> ExecuteAsync(CommandHandlerRequest request, CancellationToken cancellationToken) { QueuePolicy policy = GetQueuePolicy(request); if (policy == QueuePolicy.NoQueue) { return(await this.inner.ExecuteAsync(request, cancellationToken)); } return(await policy.ExecuteAsync(request, cancellationToken)); }
public Task <HandlerResponse> ExecuteAsync(CommandHandlerRequest request, CancellationToken cancellationToken) { return(this.TraceWriter.TraceBeginEnd( request, TraceCategories.RequestsCategory, TraceLevel.Info, this.Inner.GetType().Name, ExecuteMethodName, beginTrace: null, execute: () => this.Inner.ExecuteAsync(request, cancellationToken), endTrace: null, errorTrace: null)); }
private static QueuePolicy GetQueuePolicy(CommandHandlerRequest request) { if (request == null) { throw Error.ArgumentNull("request"); } ServicesContainer servicesContainer = request.Configuration.Services; ICommandHandlerSelector handlerSelector = servicesContainer.GetHandlerSelector(); CommandHandlerDescriptor descriptor = handlerSelector.SelectHandler(request); return(descriptor.QueuePolicy); }
public void WhenCreatingHandlerWithoutParametersThenThrowsArgumentNullException() { // Assign ICommandHandlerActivator activator = new DefaultCommandHandlerActivator(); CommandHandlerRequest request = new CommandHandlerRequest(this.config, this.command.Object); CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler)); // Act // Assert ExceptionAssert.ThrowsArgumentNull(() => activator.Create(null, null), "request"); ExceptionAssert.ThrowsArgumentNull(() => activator.Create(null, descriptor), "request"); ExceptionAssert.ThrowsArgumentNull(() => activator.Create(request, null), "descriptor"); }
public void WhenValidatingInvalidValidatableObjectCommandThenReturnsFalse() { // Assign ICommandValidator validator = new DefaultCommandValidator(); ICommand command = new ValidatableObjectCommand(false); CommandHandlerRequest request = new CommandHandlerRequest(this.configuration, command); // Act bool result = validator.Validate(request); // Assert Assert.False(result); Assert.Equal(2, request.ModelState.Sum(kvp => kvp.Value.Errors.Count)); }
public void WhenValidatingValidValidatableObjectCommandThenReturnsTrue() { // Assign ICommandValidator validator = new DefaultCommandValidator(); ICommand command = new ValidatableObjectCommand(true); CommandHandlerRequest request = new CommandHandlerRequest(this.configuration, command); // Act bool result = validator.Validate(request); // Assert Assert.True(result); Assert.Equal(0, request.ModelState.Count); }
public void WhenExecutedFilterVaryByParamsSetIncorrectlyThenCacheIsAlwaysUsed() { // Arrange CacheAttribute filter = this.CreateAttribute(new MemoryCache("test")); filter.Duration = 10; filter.VaryByParams = "XXXX"; CommandHandlerDescriptor descriptor = new CommandHandlerDescriptor(this.config, typeof(SimpleCommand), typeof(SimpleCommandHandler)); SimpleCommand command1 = new SimpleCommand { Property1 = 1, Property2 = "test1" }; CommandHandlerRequest request1 = new CommandHandlerRequest(this.config, command1); CommandHandlerContext context1 = new CommandHandlerContext(request1, descriptor); CommandHandlerExecutedContext executedContext1 = new CommandHandlerExecutedContext(context1, null); executedContext1.SetResponse("result1"); SimpleCommand command2 = new SimpleCommand { Property1 = 2, Property2 = "test2" }; CommandHandlerRequest request2 = new CommandHandlerRequest(this.config, command2); CommandHandlerContext context2 = new CommandHandlerContext(request2, descriptor); CommandHandlerExecutedContext executedContext2 = new CommandHandlerExecutedContext(context2, null); executedContext2.SetResponse("result2"); SimpleCommand command3 = new SimpleCommand { Property1 = 2, Property2 = "test3" }; CommandHandlerRequest request3 = new CommandHandlerRequest(this.config, command3); CommandHandlerContext context3 = new CommandHandlerContext(request3, descriptor); CommandHandlerExecutedContext executedContext3 = new CommandHandlerExecutedContext(context3, null); executedContext3.SetResponse("result3"); // Act filter.OnCommandExecuting(context1); filter.OnCommandExecuted(executedContext1); filter.OnCommandExecuting(context2); filter.OnCommandExecuted(executedContext2); filter.OnCommandExecuting(context3); filter.OnCommandExecuted(executedContext3); // Assert Assert.Equal("result1", executedContext1.Response.Value); Assert.Equal("result1", executedContext2.Response.Value); Assert.Equal("result1", executedContext3.Response.Value); }
public void WhenCreatingInstanceThenPropertiesAreDefined() { // Arrange Mock <ICommand> command = new Mock <ICommand>(); // Act CommandHandlerRequest request = new CommandHandlerRequest(this.defaultConfig, command.Object); // Assert Assert.Null(request.ParentRequest); Assert.Same(this.defaultConfig, request.Configuration); Assert.Same(command.Object, request.Command); Assert.Equal(command.Object.GetType(), request.MessageType); Assert.NotEqual(Guid.Empty, request.Id); }
public void WhenSelectingHandlerThenReturnHandlerDesciptor() { // Assign DefaultCommandHandlerSelector resolver = this.CreateTestableService(); CommandHandlerRequest request = new CommandHandlerRequest(this.config, new SimpleCommand()); this.config.Services.Replace(typeof(ICommandHandlerTypeResolver), new SimpleCommandHandlerTypeResolver()); // Act var descriptor = resolver.SelectHandler(request); // Assert Assert.NotNull(descriptor); Assert.Equal(typeof(SimpleHandler1), descriptor.HandlerType); Assert.Equal(typeof(SimpleCommand), descriptor.MessageType); }