static void Main(string[] args)
        {
            EventBus bus = new EventBus();
            _eventStore = new MemoryEventStore(bus);

            IEventSourcedRepository<Column> eventSourcedRepository = UseSnapshotting
                ? CreateSnapshottingRepository(EventsPerSnapshot)
                : CreateNonSnapshottingRepository();

            ColumnCommandHandler commandHandler = new ColumnCommandHandler(eventSourcedRepository);
            _columnRepository = new MemoryRepository<ColumnDTO>();
            _calculationRepository = new MemoryRepository<CalculationDTO>();
            ColumnView columnView = new ColumnView(_columnRepository);
            CalculationView calculationView = new CalculationView(_calculationRepository);

            //bus.Subscribe<IEvent>(ev => _log.Information("New Event: {@Event}", ev));

            bus.Subscribe<ColumnCreated>(columnView.Handle);
            bus.Subscribe<ColumnRenamed>(columnView.Handle);
            bus.Subscribe<ColumnDataTypeChanged>(columnView.Handle);
            bus.Subscribe<ColumnMadePrimary>(columnView.Handle);
            bus.Subscribe<ColumnPrimaryCleared>(columnView.Handle);
            bus.Subscribe<CalculationAdded>(columnView.Handle);
            bus.Subscribe<CalculationRemoved>(columnView.Handle);

            bus.Subscribe<CalculationAdded>(calculationView.Handle);
            bus.Subscribe<CalculationRemoved>(calculationView.Handle);
            bus.Subscribe<CalculationOperandChanged>(calculationView.Handle);
            bus.Subscribe<CalculationOperatorChanged>(calculationView.Handle);

            PerformSomeActions(commandHandler);
            ShowReadModel();

            PerformLotsOfActions(commandHandler);
        }
        public RandomCommandRunner(IEnumerable<Guid> potentialColumnIds, ColumnCommandHandler columnCommandHandler, IRepository<ColumnDTO> columnRepository)
        {
            _potentialColumns = potentialColumnIds.ToDictionary(id => id, id => false);
            _columnCommandHandler = columnCommandHandler;
            _columnRepository = columnRepository;

            _commandFactories = new List<Func<Guid, ICommand>>
            {
                RenameColumn,
                ChangeDataType,
                MakePrimary,
                ClearPrimary,
                AddCalculation,
                ChangeOperator,
                ChangeOperand,
                RemoveCalculation
            };
        }
        private static void PerformLotsOfActions(ColumnCommandHandler commandHandler)
        {
            var randomRunner = new RandomCommandRunner(Enumerable.Range(1, ColumnCount).Select(i => Some.Guid()), commandHandler, _columnRepository);

            List<int> averageFinalCommandsPerSecond= new List<int>();

            for (var i = 0; i < NumProfileIterations; i++)
            {
                var results = randomRunner.RunSomeCommands(CommandsPerProfileBatch);
                Console.WriteLine("{0} Columns, {1} Calculations", _columnRepository.All.Count(), _calculationRepository.All.Count());
                Console.WriteLine("{0} commands: {1} succeeded, {2} failed, {3} conflicts", results.Total, results.SuccessCount, results.FailureCount, results.ConflictCount);
                Console.WriteLine("  {0} commands per second", results.CommandsPerSecond);
                Console.WriteLine();

                if (i > NumProfileIterations - 5)
                    averageFinalCommandsPerSecond.Add(results.CommandsPerSecond);
            }

            Console.WriteLine("Average: {0:#} Commands Per Second", averageFinalCommandsPerSecond.Average());
        }
        private static void PerformSomeActions(ColumnCommandHandler commandHandler)
        {
            Guid id = Guid.NewGuid();
            commandHandler.Apply(new CreateColumn
            {
                Id = id,
                Name = "Column Name",
                DataType = DataType.Text
            });

            commandHandler.Apply(new RenameColumn
            {
                Id = id,
                Name = "New Column Name"
            });

            commandHandler.Apply(new MakeColumnPrimary
            {
                Id = id
            });

            commandHandler.Apply(new ChangeColumnDataType
            {
                Id = id,
                DataType = DataType.Date
            });

            commandHandler.Apply(new ChangeColumnDataType
            {
                Id = id,
                DataType = DataType.Number
            });

            Guid calculationId = Guid.NewGuid();
            commandHandler.Apply(new AddCalculation
            {
                Id = id,
                CalculationId = calculationId,
                Operator = Operator.Multiply,
                Operand = 3
            });

            commandHandler.Apply(new ChangeOperand
            {
                Id = id,
                CalculationId = calculationId,
                Operand = 2
            });

            commandHandler.Apply(new ChangeOperator
            {
                Id = id,
                CalculationId = calculationId,
                Operator = Operator.Divide,
            });

            commandHandler.Apply(new AddCalculation
            {
                Id = id,
                CalculationId = Guid.NewGuid(),
                Operator = Operator.Multiply,
                Operand = 3
            });

            commandHandler.Apply(new AddCalculation
            {
                Id = id,
                CalculationId = Guid.NewGuid(),
                Operator = Operator.Add,
                Operand = 98
            });
        }