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);
        }
예제 #3
0
        public async Task HandleAsync(DomainCommandTransportMessage <TAggregateRootId> message, CancellationToken token = default)
        {
            var command                   = message.DomainCommand;
            var commandId                 = command.Id;
            var commandType               = command.GetType().FullName;
            var aggregateRootId           = command.AggregateRootId;
            var aggregateRootType         = command.AggregateRootType;
            var aggregateRootTypeFullName = aggregateRootType.FullName;
            var aggregateRootStringId     = command.AggregateRootId.ToString();

            var aggregate = _cache.Get(aggregateRootStringId, aggregateRootType) ??
                            await _stateBackend.GetAsync(aggregateRootId, aggregateRootType, token);

            if (aggregate == null)
            {
                _logger.LogCritical($"Failed to restore aggregate root: [Id: {aggregateRootStringId}, Type: {aggregateRootTypeFullName}] for domain command: [Id: {commandId}, Type: {commandType}] from cache and state backend.");

                return;
            }

            aggregate.MutatingDomainEvents?.Clear();
            aggregate.MutatingDomainNotifications?.Clear();

            try
            {
                var context = AggregateRootMessagingContext.Singleton.SetServiceProvider(_serviceProvider);
                var result  = aggregate.HandleDomainCommand(context, command);
                if (!result.Succeed())
                {
                    _logger.LogError($"Handling domain command: [Id: {commandId}, Type: {commandType}] has a error: {result.Message}.");

                    return;
                }
            }
            catch (Exception e) when(e.InnerException is DomainException domainException)
            {
                await ProcessDomainExceptionAsync(command, domainException, token);

                return;
            }
            catch (Exception e)
            {
                await ProcessUnKnownExceptionAsync(command, e, token);

                return;
            }

            var hasDomainEvent       = false;
            var mutatingDomainEvents = aggregate.MutatingDomainEvents;

            if (mutatingDomainEvents.IsNotEmpty())
            {
                hasDomainEvent = true;

                await ProcessMutatingDomainEventsAsync(aggregate.MutatingDomainEvents, command, token);
            }

            var hasDomainNotification       = false;
            var mutatingDomainNotifications = aggregate.MutatingDomainNotifications;

            if (mutatingDomainNotifications.IsNotEmpty())
            {
                hasDomainNotification = true;

                await ProcessMutatingDomainNotificationsAsync(mutatingDomainNotifications, command, token);
            }

            if (!hasDomainEvent && !hasDomainNotification)
            {
                _logger.LogWarning($"The domain command: [Id: {commandId}, Type: {commandType}] apply neither domain event nor generate domain notification for aggregate root: [Id: {aggregateRootStringId}, Type: {aggregateRootTypeFullName}], please confirm whether the state will be lost.");
            }

            if (command.NeedReplyApplicationCommand())
            {
                await ReplyApplicationCommandAsync(command, token);
            }
        }
예제 #4
0
 public void Handle(DomainCommandTransportMessage <TAggregateRootId> message) => HandleAsync(message).SyncRun();