public AssembledComponents AssembleComponents()
        {
            var documents = CreateNuclear(new DocumentStrategy());
            var streamer = Streamer;

            var tapes = Tapes;
            var streaming = Streaming;
            var routerQueue = CreateQueueWriter(Topology.RouterQueue);
            var aggregates = new AggregateFactory(tapes, streamer, routerQueue);
            var sender = new SimpleMessageSender(streamer, routerQueue);
            var flow = new MessageSender(sender);

            var builder = new CqrsEngineBuilder(streamer);

            var log = tapes.GetOrCreateStream(Topology.DomainLogName);
            var dispatcher = new SimpleDispatcher(aggregates, streamer, log);

            builder.Handle(CreateInbox(Topology.RouterQueue),
                Topology.Route(CreateQueueWriter, streamer, tapes), "router");
            builder.Handle(CreateInbox(Topology.EntityQueue), aggregates.Dispatch);

            var functions = new RedirectToDynamicEvent();
            // documents
            //functions.WireToWhen(new RegistrationUniquenessProjection(atomic.Factory.GetEntityWriter<unit, RegistrationUniquenessDocument>()));

            // UI projections
            var projectionStore = CreateNuclear(new ProjectionStrategy());
            foreach (var projection in BootstrapProjections.BuildProjectionsWithWhenConvention(projectionStore.Factory))
            {
                functions.WireToWhen(projection);
            }

            // processes
            //functions.WireToWhen(new Domain.RecipeProcess(flow));

            builder.Handle(CreateInbox(Topology.EventsQueue), aem => CallHandlers(functions, aem));

            var timer = new StreamingTimerService(CreateQueueWriter(Topology.RouterQueue),
                streaming.GetContainer(Topology.FutureMessagesContainer), streamer);
            builder.Handle(CreateInbox(Topology.TimerQueue), timer.PutMessage);
            builder.AddProcess(timer);

            // GNS: just for this simple sample. In reality one would have some command handlers involved
            Bus.SetBus(new SimpleBus(sender, dispatcher));

            return new AssembledComponents
                {
                    Builder = builder,
                    Sender = sender,
                    Dispatcher = dispatcher,
                    ProjectionFactory = projectionStore.Factory,
                    Setup = this
                };
        }
        public void Test()
        {
            var streamer = EnvelopeStreamer.CreateDefault(typeof(SecondPassed));
            var builder = new CqrsEngineBuilder(streamer);
            var store = FileStorage.CreateConfig(GetType().Name, reset:true);

            builder.Handle(store.CreateInbox("inbox"), BuildRouter(store, streamer));
            builder.Handle(store.CreateInbox("process"), ie => Console.WriteLine("Message from past!"));

            var inboxWriter = store.CreateQueueWriter("inbox");
            var futureContainer = store.CreateStreaming().GetContainer("future");
            var timer = new StreamingTimerService(inboxWriter, futureContainer, streamer);

            builder.AddProcess(timer);
            builder.Handle(store.CreateInbox("timer"), timer.PutMessage);

            using (var engine = builder.Build())
            {
                var bytes = streamer.SaveEnvelopeData(new SecondPassed(), c => c.DelayBy(TimeSpan.FromSeconds(4)));
                inboxWriter.PutMessage(bytes);
                Console.WriteLine("Sent message to future...");
                engine.RunForever();
            }
        }