Ejemplo n.º 1
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.º 2
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.º 3
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.º 4
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.º 5
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);
        }
Ejemplo n.º 6
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.º 7
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.º 8
0
        public static IDomainNotification FillFrom(this IDomainNotification notification, IDomainCommand command)
        {
            notification.AggregateRootType             = command.AggregateRootType.FullName;
            notification.AggregateRootId               = command.AggregateRootId;
            notification.DomainCommandId               = command.Id;
            notification.DomainCommandType             = command.GetType().FullName;
            notification.Topic                         = command.Topic;
            notification.PartitionKey                  = command.PartitionKey;
            notification.ApplicationCommandId          = command.ApplicationCommandId;
            notification.ApplicationCommandType        = command.ApplicationCommandType;
            notification.ApplicationCommandReplyScheme = command.ApplicationCommandReplyScheme;

            return(notification);
        }
Ejemplo n.º 9
0
        public static IDomainExceptionMessage FillFrom(this IDomainExceptionMessage exception, IDomainCommand command)
        {
            exception.AggregateRootType             = command.AggregateRootType.FullName;
            exception.AggregateRootId               = command.AggregateRootId;
            exception.DomainCommandId               = command.Id;
            exception.DomainCommandType             = command.GetType().FullName;
            exception.Topic                         = command.Topic;
            exception.PartitionKey                  = command.PartitionKey;
            exception.ApplicationCommandId          = command.ApplicationCommandId;
            exception.ApplicationCommandType        = command.ApplicationCommandType;
            exception.ApplicationCommandReplyScheme = command.ApplicationCommandReplyScheme;

            return(exception);
        }
        public async Task SaveCommandAsync <TAggregate>(IDomainCommand command) where TAggregate : IAggregateRoot
        {
            await Task.CompletedTask;

            EnsureAggregateExists <TAggregate>(command.AggregateRootId);

            var commandDocument = new CommandDocument()
            {
                Id          = Guid.NewGuid(),
                AggregateId = command.AggregateRootId,
                Type        = command.GetType().AssemblyQualifiedName,
                Data        = JsonConvert.SerializeObject(command),
                TimeStamp   = command.TimeStamp,
                UserId      = command.UserId,
                Source      = command.Source
            };

            Commands.Add(commandDocument);
        }
Ejemplo n.º 11
0
        private async Task ProcessUnKnownExceptionAsync(IDomainCommand command, Exception exception, CancellationToken token)
        {
            _logger.LogError($"Handling domain command[Id: {command.Id}, Type: {command.GetType().FullName}, application command[{command.ApplicationCommandId}, {command.ApplicationCommandType}, reply scheme: {command.ApplicationCommandReplyScheme}], aggregate root[{command.AggregateRootId},{command.AggregateRootType.FullName}], has a unknown exceptionException: {LogFormatter.PrintException(exception)}.");

            var canReturnOnDomainCommandHandled = command.ApplicationCommandReplyScheme == ApplicationCommandReplySchemes.OnDomainCommandHandled;

            if (!canReturnOnDomainCommandHandled)
            {
                return;
            }

            var domainExceptionMessage = new DomainExceptionMessage()
            {
                Message = exception.Message
            };

            domainExceptionMessage.FillFrom(command);

            await PublishDomainExceptionAsync(domainExceptionMessage, token);
        }
Ejemplo n.º 12
0
        private async Task ProcessDomainExceptionAsync(IDomainCommand command, DomainException domainException, CancellationToken token)
        {
            var commandId   = command.Id;
            var commandType = command.GetType().FullName;
            var canReturnOnDomainCommandHandled = command.ApplicationCommandReplyScheme == ApplicationCommandReplySchemes.OnDomainCommandHandled;

            _logger.LogError($"Handling domain command has a domain exception, Id: {commandId}, Type: {commandType}, Exception: {LogFormatter.PrintException(domainException)}.");

            if (!canReturnOnDomainCommandHandled)
            {
                return;
            }

            var domainExceptionMessage = new DomainExceptionMessage()
            {
                Message = domainException.Message,
                Code    = domainException.Code
            };

            domainExceptionMessage.FillFrom(command);

            await PublishDomainExceptionAsync(domainExceptionMessage, token);
        }
 public StoreCommand(Guid id, IDomainCommand command) : base(id)
 {
     Type = command.GetType();
     TypeName = command.GetType().Name;
     Command = command;
 }
Ejemplo n.º 14
0
 public async Task Publish(IDomainCommand domainCommand)
 {
     await _serviceProvider.GetServices <IDomainCommandHandler>()
     .FirstOrDefault(x => x.CanHandle(domainCommand.GetType()))
     .HandleAsync(domainCommand);
 }