Esempio n. 1
0
        private async Task <object> ProcessNextMiddleware <T>(T command, ICommandBusMiddleware <T>[] middlewares,
                                                              int middlewareIndex, CommandBusMiddlewareDelegate executionHandler,
                                                              CommandExecutionOptions executionOptions, CancellationToken cancellationToken)
            where T : class, ICommandBase
        {
            CommandBusMiddlewareDelegate next;

            if (middlewareIndex == middlewares.Length - 1)
            {
                next = executionHandler;
            }
            else
            {
                next = async processedCommand =>
                {
                    var typedCommand = processedCommand as T
                                       ?? throw new ArgumentException(
                                                 $"Command passed to command bus middleware ({processedCommand?.GetType()}) is not of original type {typeof(T)}");
                    return(await ProcessNextMiddleware <T>(typedCommand, middlewares,
                                                           middlewareIndex + 1, executionHandler, executionOptions, cancellationToken));
                };
            }

            return(await middlewares[middlewareIndex].HandleAsync(command, executionOptions, next, cancellationToken));
        }
Esempio n. 2
0
        private async Task <object> HandleNext(ICommandBase command, CommandBusMiddlewareDelegate next,
                                               IUnitOfWork unitOfWork)
        {
            ICommandContext newContext = new CommandContext(command, unitOfWork);

            commandContextStack.Push(newContext);

            newContext.UnitOfWork?.Begin();
            try
            {
                var result = await next(command);

                if (newContext.UnitOfWork != null)
                {
                    await newContext.UnitOfWork.CommitAsync();
                }

                return(result);
            }
            finally
            {
                Debug.Assert(commandContextStack.PeekOrDefault == newContext);
                commandContextStack.Pop();
            }
        }
        public async Task HandleAsync_ReturnsResult()
        {
            var query = new Query1();
            CommandBusMiddlewareDelegate next = async paramCommand => 42;

            var result = await sut.HandleAsync(query, CommandExecutionOptions.Default,
                                               next, CancellationToken.None);

            result.Should().Be(42);
        }
        public async Task HandleAsync_PopsCommandContextOnException()
        {
            var command = new Command1();
            CommandBusMiddlewareDelegate next = async paramCommand => { throw new Exception(); };

            await sut.Awaiting(x => x.HandleAsync(command, CommandExecutionOptions.Default,
                                                  next, CancellationToken.None)).Should().ThrowExactlyAsync <Exception>();

            commandContextStack.PeekOrDefault.Should().BeNull();
        }
Esempio n. 5
0
        public Task <object> ProcessAsync(ICommandBase command, CommandBusMiddlewareDelegate executionHandler,
                                          ICommandBus commandBus, CommandExecutionOptions executionOptions, CancellationToken cancellationToken)
        {
            var processMethod      = GetType().GetRuntimeMethods().Single(x => x.Name == "ProcessInternalAsync");
            var boundProcessMethod = processMethod.MakeGenericMethod(command.GetType());

            return((Task <object>)boundProcessMethod.Invoke(this, new object[]
            {
                command, executionHandler, commandBus, executionOptions, cancellationToken
            }));
        }
        public async Task HandleAsync_DoesNotCommitWhenConfigured()
        {
            var command = new Command1();
            CommandBusMiddlewareDelegate next = async paramCommand =>
            {
                commandContextStack.UnitOfWork.Should().BeNull();
                return(null);
            };

            await sut.HandleAsync(command, new CommandExecutionOptions(false, null),
                                  next, CancellationToken.None);

            unitOfWorkFactory.DidNotReceive().CreateUnitOfWork();
        }
        public async Task HandleAsync_DoesNotCommitForQueries()
        {
            var query = new Query1();
            CommandBusMiddlewareDelegate next = async paramCommand =>
            {
                commandContextStack.UnitOfWork.Should().BeNull();
                return(null);
            };

            await sut.HandleAsync(query, CommandExecutionOptions.Default,
                                  next, CancellationToken.None);

            unitOfWorkFactory.DidNotReceive().CreateUnitOfWork();
        }
Esempio n. 8
0
 public async Task <object> HandleAsync(ICommandBase command, CommandExecutionOptions executionOptions,
                                        CommandBusMiddlewareDelegate next, CancellationToken cancellationToken)
 {
     if (executionOptions.TenantContext != null)
     {
         using (TenantContextOverride.Push(executionOptions.TenantContext.Tenant))
         {
             return(await next(command));
         }
     }
     else
     {
         return(await next(command));
     }
 }
        public async Task HandleAsync_CommitsWhenConfigured()
        {
            var query = new Query1();
            CommandBusMiddlewareDelegate next = async paramCommand =>
            {
                commandContextStack.UnitOfWork.Should().Be(unitOfWork);
                return(null);
            };

            await sut.HandleAsync(query, new CommandExecutionOptions(true, null),
                                  next, CancellationToken.None);

            unitOfWorkFactory.Received(1).CreateUnitOfWork();
            unitOfWork.Received(1).CommitAsync();
        }
        public async Task HandleAsync_CommitsForCommands()
        {
            var command = new Command1();
            CommandBusMiddlewareDelegate next = async paramCommand =>
            {
                commandContextStack.UnitOfWork.Should().Be(unitOfWork);
                return(null);
            };

            await sut.HandleAsync(command, CommandExecutionOptions.Default,
                                  next, CancellationToken.None);

            unitOfWorkFactory.Received(1).CreateUnitOfWork();
            unitOfWork.Received(1).CommitAsync();
        }
Esempio n. 11
0
 public Task <object> HandleAsync(ICommandBase command, CommandExecutionOptions executionOptions,
                                  CommandBusMiddlewareDelegate next, CancellationToken cancellationToken)
 {
     if (executionOptions.AutoCommitUnitOfWork == true ||
         (executionOptions.AutoCommitUnitOfWork == null && !IsQuery(command)))
     {
         using (var uow = unitOfWorkFactory.CreateUnitOfWork())
         {
             return(HandleNext(command, next, uow));
         }
     }
     else
     {
         return(HandleNext(command, next, null));
     }
 }
Esempio n. 12
0
        public async Task <object> HandleAsync(T command, CommandExecutionOptions executionOptions,
                                               CommandBusMiddlewareDelegate next, CancellationToken cancellationToken)
        {
            await PreFilterAsync(command);

            try
            {
                var result = await next(command);
                await PostFilterAsync(command);

                return(result);
            }
            catch (Exception e)
            {
                await FilterExceptionAsync(command, e);

                throw;
            }
        }
Esempio n. 13
0
        private async Task <object> ProcessInternalAsync <T>(T command, CommandBusMiddlewareDelegate executionHandler,
                                                             ICommandBus commandBus, CommandExecutionOptions executionOptions, CancellationToken cancellationToken)
            where T : class, ICommandBase
        {
            using (TaskContext.Enter())
            {
                var middlewares = middlewareFactory.CreateMiddlewares <T>(commandBus);

                if (middlewares.Length == 0)
                {
                    return(executionHandler(command));
                }

                middlewares = middlewares.OrderBy(x => x.Order).ToArray();

                return(await ProcessNextMiddleware(command, middlewares, 0, executionHandler,
                                                   executionOptions, cancellationToken));
            }
        }
Esempio n. 14
0
        private async Task <TResult> InvokeHandleAsync <TResult>(Type handlerType, ICommandBase command, CommandExecutionOptions executionOptions,
                                                                 CancellationToken cancellationToken)
        {
            CommandBusMiddlewareDelegate executionHandler = async processedCommand =>
            {
                if (processedCommand == null)
                {
                    throw new ArgumentNullException(nameof(processedCommand));
                }

                if (!command.GetType().IsInstanceOfType(processedCommand))
                {
                    throw new ArgumentException(
                              $"Command passed back to command bus from a middleware is not of its original type {command.GetType()}");
                }

                Type   commandType  = command.GetType();
                object listener     = serviceLocator.Get(handlerType);
                var    handleMethod = listener.GetType()
                                      .GetRuntimeMethod(nameof(ICommandHandler <ICommand> .HandleAsync),
                                                        new[] { commandType, typeof(CancellationToken) });

                var resultTask = (Task)handleMethod.Invoke(listener, new object[] { command, cancellationToken });

                if (resultTask is Task <TResult> resultObjectTask)
                {
                    return(await resultObjectTask);
                }
                else
                {
                    await resultTask;
                    return(null);
                }
            };

            object result = await pipeline.ProcessAsync(command, executionHandler, this,
                                                        executionOptions, cancellationToken);

            return((TResult)result);
            // TODO test with contravariant handlers
        }
        public async Task HandleAsync_PushesAndPopsCommandContext()
        {
            var command        = new Command1();
            var expectedResult = new object();

            int invokedNext = 0;
            CommandBusMiddlewareDelegate next = async paramCommand =>
            {
                paramCommand.Should().Be(command);
                commandContextStack.CurrentCommand.Should().Be(command);
                unitOfWorkFactory.Received(1).CreateUnitOfWork();
                commandContextStack.UnitOfWork.Should().Be(unitOfWork);
                invokedNext++;
                return(expectedResult);
            };

            var result = await sut.HandleAsync(command, CommandExecutionOptions.Default,
                                               next, CancellationToken.None);

            invokedNext.Should().Be(1);
            result.Should().Be(expectedResult);

            commandContextStack.PeekOrDefault.Should().BeNull();
        }