public void PassThrough()
        {
            var context = Substitute.For<IUpstreamContext>();
            var state = new CommandCompleted(new DispatchCommand(new FakeCommand(), 3));
            var dispatcher = new RetryingHandler(3);

            dispatcher.HandleUpstream(context, state);

            context.Received().SendUpstream(Arg.Any<CommandCompleted>());
        }
        public void FailTwo()
        {
            var context = Substitute.For<IUpstreamContext>();
            var msg = new CommandFailed(new DispatchCommand(new FakeCommand(), 1), new Exception());
            var dispatcher = new RetryingHandler(3);

            dispatcher.HandleUpstream(context, msg);

            context.Received().SendUpstream(Arg.Any<CommandFailed>());
            context.Received().SendDownstream(Arg.Any<DispatchCommand>());
            context.DidNotReceive().SendUpstream(Arg.Any<CommandAborted>());
        }
        /// <summary>
        /// Build the dispatcher.
        /// </summary>
        /// <returns>Created dispatcher</returns>
        public ICommandDispatcher Build()
        {
            if (_lastHandler == null && _container == null)
                throw new InvalidOperationException(
                    "You must have specified a handler which can actually invoke the correct command handler. For instance the 'IocDispatcher'.");
            if (_container == null && _lastHandler == null)
                throw new InvalidOperationException(
                    "You must have specified a SINGLE handler that can invoke the correct command handler. Either use 'IocDispatcher' or another one, not both alternatives.");

            var builder = new PipelineBuilder();

            // must be registered before the storage since the storage listens on CommandAborted
            if (_maxAttempts > 0)
            {
                var handler = new RetryingHandler(_maxAttempts);
                builder.RegisterUpstream(handler);
            }

            // Must be registered before the async handler.
            if (_storageHandler != null)
            {
                builder.RegisterDownstream(_storageHandler);
                builder.RegisterUpstream(_storageHandler);
            }


            if (_workers > 0)
                builder.RegisterDownstream(new AsyncHandler(_workers));

            if (_container != null)
                builder.RegisterDownstream(new Pipeline.IocDispatcher(_container));
            else
                builder.RegisterDownstream(_lastHandler);

            builder.RegisterUpstream(_errorHandler);
            var pipeline = builder.Build();
            pipeline.Start();
            var dispatcher = new PipelineDispatcher(pipeline);
            return dispatcher;
        }