Ejemplo n.º 1
0
        public void Save(Type aggregateType, Guid aggregateRootId, IDomainCommand command, IEnumerable <IDomainEvent> events)
        {
            var aggregateFilter = Builders <AggregateDocument> .Filter.Eq("_id", aggregateRootId.ToString());

            var aggregateDocument = _dbContext.Aggregates.Find(aggregateFilter).FirstOrDefault();

            if (aggregateDocument == null)
            {
                var newAggregateDocument = _aggregateDocumentFactory.CreateAggregate(aggregateType, aggregateRootId);
                _dbContext.Aggregates.InsertOne(newAggregateDocument);
            }

            if (command != null)
            {
                var commandDocument = _commandDocumentFactory.CreateCommand(command);
                _dbContext.Commands.InsertOne(commandDocument);
            }

            foreach (var @event in events)
            {
                var eventFilter = Builders <EventDocument> .Filter.Eq("aggregateId", @event.AggregateRootId.ToString());

                var currentVersion = _dbContext.Events.Find(eventFilter).CountDocuments();
                var nextVersion    = _versionService.GetNextVersion(@event.AggregateRootId, (int)currentVersion, command?.ExpectedVersion);

                var eventDocument = _eventDocumentFactory.CreateEvent(@event, nextVersion);

                _dbContext.Events.InsertOne(eventDocument);
            }
        }
Ejemplo n.º 2
0
        private void ApplyBusinessRules(IDomainCommand command)
        {
            this.Monitor();

            /**
             * Here we can call Business Rules to validate and do whatever.
             * Then, based on the outcome generated events.
             * In this example, we are simply going to accept it and updated our state.
             */
            var result = AccountBusinessRulesManager.ApplyBusinessRules(_accountState, command);

            _log.Info($"There were {result.GeneratedEvents.Count} events for {command.ToString()} command. And it was {result.Success}");
            _log.Info($"And it returned {result.Success}");
            if (result.Success)
            {
                /* I may want to do old vs new state comparisons for other reasons
                 *  but ultimately we just update the state.. */
                var events = result.GeneratedEvents;
                foreach (var @event in events)
                {
                    _log.Info($"Event: {@event.ToString()}");
                    Persist(@event, s =>
                    {
                        _accountState = _accountState.Event(@event);
                        ApplySnapShotStrategy();
                        _log.Info($"Processing event {@event.ToString()} from business rules for command {command.ToString()}");
                    });
                }
            }
        }
Ejemplo n.º 3
0
        private void HandleCommand(HandlerStore handlerStore, IDomainCommand domainMessage)
        {
            var currentTuple = Tuple.Create(handlerStore, domainMessage);

            HandleMessage(currentTuple.Item1, currentTuple.Item2, 1);

            /*     do
             *   {
             *       lock (_runningCommands)
             *       {
             *           if (_runningCommands.Contains(currentTuple.Item2.Id.ToString()))
             *           {
             *               _delayedCommands.Enqueue(currentTuple);
             *               currentTuple = null;
             *           }
             *           else
             *           {
             *               _runningCommands.Add(domainMessage.Id.ToString());
             *           }
             *       }
             *
             *       if (currentTuple != null)
             *       {
             *           HandleMessage(currentTuple.Item1, currentTuple.Item2,1);
             *           lock (_runningCommands)
             *           {
             *               _runningCommands.Remove(currentTuple.Item2.Id.ToString());
             *           }
             *       }
             *       _delayedCommands.TryDequeue(out currentTuple);
             *
             *   }
             *   while (currentTuple != null);
             */
        }
Ejemplo n.º 4
0
 private static Type GetAggregateType(IDomainCommand domainCommand)
 {
     var commandType = domainCommand.GetType();
     var commandInterface = commandType.GetInterfaces()[1];
     var aggregateType = commandInterface.GetGenericArguments().FirstOrDefault();
     return aggregateType;
 }
Ejemplo n.º 5
0
        public static bool NeedReplyApplicationCommand(this IDomainCommand command)
        {
            var needReply = command.ApplicationCommandReplyScheme == ApplicationCommandReplySchemes.OnDomainCommandHandled;

            if (!needReply)
            {
                return(false);
            }

            var isEnd = command is IEndSubTransactionDomainCommand;

            if (isEnd)
            {
                return(true);
            }

            var isBegin = command is IBeginSubTransactionDomainCommand;

            if (isBegin)
            {
                return(false);
            }

            return(!(command is ISubTransactionDomainCommand));
        }
Ejemplo n.º 6
0
 public T Execute <T>(IDomainCommand <T> command)
 {
     using (this)
     {
         return(command.Execute(Context));
     }
 }
Ejemplo n.º 7
0
        public async Task SaveAsync(Type aggregateType, Guid aggregateRootId, IDomainCommand command, IEnumerable <IDomainEvent> events)
        {
            var aggregateDocument = await _aggregateRepository.GetDocumentAsync(aggregateRootId.ToString());

            if (aggregateDocument == null)
            {
                var newAggregateDocument = _aggregateDocumentFactory.CreateAggregate(aggregateType, aggregateRootId);
                await _aggregateRepository.CreateDocumentAsync(newAggregateDocument);
            }

            if (command != null)
            {
                var commandDocument = _commandDocumentFactory.CreateCommand(command);
                await _commandRepository.CreateDocumentAsync(commandDocument);
            }

            foreach (var @event in events)
            {
                var currentVersion = await _eventRepository.GetCountAsync(d => d.AggregateId == @event.AggregateRootId);

                var nextVersion = _versionService.GetNextVersion(@event.AggregateRootId, currentVersion, command?.ExpectedVersion);

                var eventDocument = _eventDocumentFactory.CreateEvent(@event, nextVersion);

                await _eventRepository.CreateDocumentAsync(eventDocument);
            }
        }
Ejemplo n.º 8
0
 public void Execute(IDomainCommand command)
 {
     using (this)
     {
         command.Execute(Context);
     }
 }
Ejemplo n.º 9
0
 public void Handle(IDomainCommand cmd)
 {
     if (cmd is T)
     {
         Handle(cmd as T);
     }
 }
Ejemplo n.º 10
0
        public void Save(Type aggregateType, Guid aggregateRootId, IDomainCommand command, IEnumerable <IDomainEvent> events)
        {
            using (var dbContext = _dbContextFactory.CreateDbContext())
            {
                var aggregateEntity = dbContext.Aggregates.FirstOrDefault(x => x.Id == aggregateRootId);
                if (aggregateEntity == null)
                {
                    var newAggregateEntity = _aggregateEntityFactory.CreateAggregate(aggregateType, aggregateRootId);
                    dbContext.Aggregates.Add(newAggregateEntity);
                }

                if (command != null)
                {
                    var newCommandEntity = _commandEntityFactory.CreateCommand(command);
                    dbContext.Commands.Add(newCommandEntity);
                }

                foreach (var @event in events)
                {
                    var currentVersion = dbContext.Events.Count(x => x.AggregateId == @event.AggregateRootId);
                    var nextVersion    = _versionService.GetNextVersion(@event.AggregateRootId, currentVersion, command?.ExpectedVersion);
                    var newEventEntity = _eventEntityFactory.CreateEvent(@event, nextVersion);
                    dbContext.Events.Add(newEventEntity);
                }

                dbContext.SaveChanges();
            }
        }
        /// <summary>
        /// Project a type using a DTO
        /// </summary>
        /// <typeparam name="TProjection">
        /// The dto projection
        /// </typeparam>
        /// <param name="item">
        /// The item.
        /// </param>
        /// <returns>
        /// The projected type
        /// </returns>
        public static TProjection ProjectedAs <TProjection>(this IDomainCommand item)
            where TProjection : class, new()
        {
            var adapter = TypeAdapterFactory.CreateAdapter();

            return(adapter.Adapt <TProjection>(item));
        }
Ejemplo n.º 12
0
        public static IDomainCommand WithNotifyingContext <TAggregateRootId>(this IDomainCommand <TAggregateRootId> command, IDomainNotification notification)
        {
            command.ApplicationCommandId          = notification.ApplicationCommandId;
            command.ApplicationCommandType        = notification.ApplicationCommandType;
            command.ApplicationCommandReplyScheme = notification.ApplicationCommandReplyScheme;

            return(command);
        }
Ejemplo n.º 13
0
        internal static IDomainCommand WithEventingContext <TAggregateRootId>(this IDomainCommand <TAggregateRootId> command, IDomainEvent @event)
        {
            command.ApplicationCommandId          = @event.ApplicationCommandId;
            command.ApplicationCommandType        = @event.ApplicationCommandType;
            command.ApplicationCommandReplyScheme = @event.ApplicationCommandReplyScheme;

            return(command);
        }
Ejemplo n.º 14
0
        public static IDomainCommand FillFrom(this IDomainCommand domainCommand, IApplicationCommand applicationCommand)
        {
            domainCommand.ApplicationCommandId          = applicationCommand.Id;
            domainCommand.ApplicationCommandType        = applicationCommand.GetType().FullName;
            domainCommand.ApplicationCommandReplyScheme = applicationCommand.ReplyScheme;

            return(domainCommand);
        }
Ejemplo n.º 15
0
        public ISendCommandCallback Send(IDomainCommand command, Action <IDictionary <string, string> > configHeaders = null)
        {
            UseConfigHeaders(configHeaders);
            var callback = Bus.Send(command);
            var result   = new SendCommandCallback(callback);

            return(result);
        }
Ejemplo n.º 16
0
        public async Task HandleAsync(IDomainCommand command)
        {
            var cmd = command as AddSprintToProjectCommand;
            var pr  = await _projectRepository.GetByIdAsync(cmd.ProjectId);

            pr.AddSprint(cmd.Sprint);
            await _projectRepository.UnitOfWork.CommitAsync();
        }
Ejemplo n.º 17
0
        public static IDomainCommand <TAggregateRootId> FillFrom <TAggregateRootId>(this IDomainCommand <TAggregateRootId> domainCommand, IApplicationCommand applicationCommand)
        {
            domainCommand.ApplicationCommandId          = applicationCommand.Id;
            domainCommand.ApplicationCommandType        = applicationCommand.GetType().FullName;
            domainCommand.ApplicationCommandReplyScheme = applicationCommand.ReplyScheme;

            return(domainCommand);
        }
Ejemplo n.º 18
0
 public DomainCommandTransportMessage(string applicationCommandId, string applicationCommandType,
                                      IDomainCommand domainCommand)
 {
     ApplicationCommandId   = applicationCommandId;
     ApplicationCommandType = applicationCommandType;
     DomainCommand          = domainCommand;
     Topic        = domainCommand.Topic;
     PartitionKey = domainCommand.PartitionKey;
 }
Ejemplo n.º 19
0
        public void Tell(IDomainCommand command)
        {
            var commandType = AssertCommandHandler(command);

            if (commandType != null)
            {
                _commandHandlers[commandType](command);
            }
        }
Ejemplo n.º 20
0
        private void ExecutingDomainCommand(AggregateRootMessagingContext context, IDomainCommand command)
        {
            var methodName            = "OnDomainCommand";
            var commandType           = command.GetType();
            var commandTypeFullName   = command.GetType();
            var domainCommandType     = typeof(IDomainCommand);
            var aggregateTypeFullName = AggregateRootType.FullName;

            if (!domainCommandType.IsAssignableFrom(commandType))
            {
                throw new MethodNotFoundException($"The method: {methodName}({commandTypeFullName}) in {aggregateTypeFullName} is wrong, reason: {commandTypeFullName} cannot assign to interface: {domainCommandType.FullName}.");
            }

            var methodWithoutContext = AggregateRootType
                                       .GetMethod(methodName,
                                                  BindingFlags.Instance | BindingFlags.Public,
                                                  null,
                                                  new[] { commandType },
                                                  null);

            if (methodWithoutContext != null)
            {
                var instance       = Expression.Constant(this);
                var parameter      = Expression.Parameter(commandType, methodName);
                var call           = Expression.Call(instance, methodWithoutContext, parameter);
                var lambda         = Expression.Lambda(call, parameter);
                var methodDelegate = lambda.Compile();

                methodDelegate.DynamicInvoke(command);

                return;
            }

            var contextType       = context.GetType();
            var methodWithContext = AggregateRootType
                                    .GetMethod(methodName,
                                               BindingFlags.Instance | BindingFlags.Public,
                                               null,
                                               new[] { contextType, commandType },
                                               null);

            if (methodWithContext != null)
            {
                var instance       = Expression.Constant(this);
                var parameter1     = Expression.Parameter(contextType, $"{methodName}_0");
                var parameter2     = Expression.Parameter(commandType, $"{methodName}_1");
                var call           = Expression.Call(instance, methodWithContext, parameter1, parameter2);
                var lambda         = Expression.Lambda(call, parameter1, parameter2);
                var methodDelegate = lambda.Compile();

                methodDelegate.DynamicInvoke(context, command);

                return;
            }

            throw new MethodNotFoundException($"No {methodName}({commandTypeFullName}) found in {aggregateTypeFullName}.");
        }
Ejemplo n.º 21
0
 /// <inheritdoc />
 public void SaveCommand <TAggregate>(IDomainCommand command) where TAggregate : IAggregateRoot
 {
     using (var dbContext = _dbContextFactory.CreateDbContext())
     {
         var newCommandEntity = _commandEntityFactory.CreateCommand(command);
         dbContext.Commands.Add(newCommandEntity);
         dbContext.SaveChanges();
     }
 }
 public void Publish(IDomainCommand command)
 {
     this.Info(() => "Publishing command {0}".FormatWith(command));
     _bus.Publish(command);
     this.Info(() => "Published command {0}".FormatWith(command));
     this.Info(() => "Storing command {0}".FormatWith(command));
     _bus.Publish(new StoreCommand(Guid.NewGuid(), command));
     this.Info(() => "Stored command {0}".FormatWith(command));
 }
Ejemplo n.º 23
0
        /// <inheritdoc />
        public async Task SaveCommandAsync <TAggregate>(IDomainCommand command) where TAggregate : IAggregateRoot
        {
            using (var dbContext = _dbContextFactory.CreateDbContext())
            {
                var newCommandEntity = _commandEntityFactory.CreateCommand(command);
                await dbContext.Commands.AddAsync(newCommandEntity);

                await dbContext.SaveChangesAsync();
            }
        }
        public void Publish <TAggregateRootId>(IDomainCommand <TAggregateRootId> command)
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            var message = new DomainCommandTransportMessage <TAggregateRootId>(command);

            _messagePublisher.Publish(message);
        }
        public void Publish(IDomainCommand command)
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            var message = new DomainCommandTransportMessage(command);

            _messagePublisher.Publish(message);
        }
Ejemplo n.º 26
0
        public async Task SaveCommandAsync <TAggregate>(IDomainCommand command) where TAggregate : IAggregateRoot
        {
            var aggregateDocument = await _aggregateRepository.GetDocumentAsync(command.AggregateRootId.ToString());

            if (aggregateDocument == null)
            {
                var newAggregateDocument = _aggregateDocumentFactory.CreateAggregate <TAggregate>(command.AggregateRootId);
                await _aggregateRepository.CreateDocumentAsync(newAggregateDocument);
            }

            var commandDocument = _commandDocumentFactory.CreateCommand(command);
            await _commandRepository.CreateDocumentAsync(commandDocument);
        }
Ejemplo n.º 27
0
 public CommandEntity CreateCommand(IDomainCommand command)
 {
     return(new CommandEntity
     {
         Id = command.Id,
         AggregateId = command.AggregateRootId,
         Type = command.GetType().AssemblyQualifiedName,
         Data = JsonConvert.SerializeObject(command),
         TimeStamp = command.TimeStamp,
         UserId = command.UserId,
         Source = command.Source
     });
 }
Ejemplo n.º 28
0
 public CommandDocument CreateCommand(IDomainCommand command)
 {
     return(new CommandDocument
     {
         Id = command.Id,
         AggregateId = command.AggregateRootId,
         Type = command.GetType().AssemblyQualifiedName,
         Data = SaveCommandData(command) ? JsonConvert.SerializeObject(command) : null,
         TimeStamp = command.TimeStamp,
         UserId = command.UserId,
         Source = command.Source
     });
 }
Ejemplo n.º 29
0
 public CommandDocument CreateCommand(IDomainCommand command)
 {
     return(new CommandDocument
     {
         Id = Guid.NewGuid().ToString(),
         AggregateId = command.AggregateRootId.ToString(),
         Type = command.GetType().AssemblyQualifiedName,
         Data = JsonConvert.SerializeObject(command),
         TimeStamp = command.TimeStamp,
         UserId = command.UserId,
         Source = command.Source
     });
 }
Ejemplo n.º 30
0
 public static void FillFrom(this IEnumerable <IDomainEvent> domainEvents, IDomainCommand command)
 {
     foreach (var domainEvent in domainEvents)
     {
         domainEvent.DomainCommandId               = command.Id;
         domainEvent.DomainCommandType             = command.GetType();
         domainEvent.Topic                         = command.Topic;
         domainEvent.PartitionKey                  = command.PartitionKey;
         domainEvent.ApplicationCommandId          = command.ApplicationCommandId;
         domainEvent.ApplicationCommandType        = command.ApplicationCommandType;
         domainEvent.ApplicationCommandReplyScheme = command.ApplicationCommandReplyScheme;
     }
 }
Ejemplo n.º 31
0
        private Type AssertCommandHandler(IDomainCommand command)
        {
            // Get command type and throw error if command has no handler in aggregate
            var commandType = command.GetType();

            if (!_commandHandlers.ContainsKey(commandType))
            {
                UnhandledCommand(command);
                return(null);
            }

            return(commandType);
        }
 public StoreCommand(Guid id, IDomainCommand command) : base(id)
 {
     Type = command.GetType();
     TypeName = command.GetType().Name;
     Command = command;
 }