Exemplo n.º 1
0
        public async Task UpdateAsync(Guid userId, string emailAddress)
        {
            var user = await _userRepository.GetByIdAsync(userId);

            _subscriber.Subscribe <UserUpdatedEvent>(async domainEvent => await HandleAsync(_userUpdatedEventHandlers, domainEvent));
            user.UpdateEmailAddress(userId, emailAddress);
            await _userRepository.SaveAsync(user);
        }
Exemplo n.º 2
0
        protected async Task PerformAsync(Command <TId> cmd, Action <T> action)
        {
            var aggregate = await _repo.GetByIdAsync(cmd.AggregateId);

            var version = cmd.Version == 0 ? null : cmd.Version;

            if (cmd.Version != null && cmd.Version.Value > 0 && cmd.Version != aggregate.Version)
            {
                Trace.TraceWarning(
                    $"The supplied aggregate version {cmd.Version} is different from the loaded aggregate version {aggregate.Version}.");
            }
            action(aggregate);
            await SaveAsync(aggregate, version ?? aggregate.Version);
        }
Exemplo n.º 3
0
        public async Task <Unit> Handle(AddPaymentCommand request, CancellationToken cancellationToken)
        {
            await PerformAsync(request, async creditCard =>
            {
                var subscription = await _subscriptionRepo.GetByIdAsync(creditCard.SubscriptionId);
                subscription.AddTransactionTo(creditCard, request.Payment, request.Occured);
            });

            return(Unit.Value);
        }
Exemplo n.º 4
0
        public async Task <AggregateApplicationResult> ApplyEventAsync(BaseEvent evt)
        {
            // Lets have a constraint for item Name uniqueness
            ItemAggregate aggregate;
            BaseItemEvent itemEvent;

            switch (evt)
            {
            case ItemCreatedEvent created:
                var itemsWithSameName = await aggregatesRepository.GetByNameAsync(created.Name);

                if (itemsWithSameName.Any(x => x.LastEvent != null && !(x.LastEvent is ItemDeletedEvent)))
                {
                    return(new ItemAlreadyExistsApplicationResult("Item with the same name already exists"));
                }

                aggregate = new ItemAggregate(created.ItemId);
                itemEvent = created;
                break;

            case ItemDeletedEvent deleted:
                aggregate = await aggregatesRepository.GetByIdAsync(deleted.ItemId);

                if (aggregate == null || aggregate.LastEvent == null)
                {
                    return(new ItemNotFoundApplicationResult());
                }

                if (aggregate.LastEvent is ItemDeletedEvent)
                {
                    // It is already deleted
                    return(new SuccessAggregateApplicationResult());
                }

                itemEvent = deleted;
                break;

            case ItemUpdatedEvent updated:
                aggregate = await aggregatesRepository.GetByIdAsync(updated.ItemId);

                if (aggregate == null || aggregate.LastEvent == null || aggregate.LastEvent is ItemDeletedEvent)
                {
                    return(new ItemNotFoundApplicationResult());
                }

                if (aggregate.LastEvent is ItemUpdatedEvent lastUpdated && lastUpdated.Name.Equals(updated.Name))
                {
                    // This aggregate has already got this name
                    return(new SuccessAggregateApplicationResult());
                }

                // Looking for another aggregate with this name
                var itemsWithSameNameForUpdate = await aggregatesRepository.GetByNameAsync(updated.Name);

                if (itemsWithSameNameForUpdate.Any(x => x.LastEvent != null && !(x.LastEvent is ItemDeletedEvent)))
                {
                    return(new ItemAlreadyExistsApplicationResult("Item with the same name already exists"));
                }

                itemEvent = updated;
                break;

            default:
                return(new FailedAggregateApplicationResult($"Specified event type {evt.GetType().Name} is not supported"));
            }

            var applicationResult = aggregate.ApplyEvent(itemEvent);

            switch (applicationResult)
            {
            case SuccessAggregateApplicationResult success:
                // This method might be a root specific, because of several aggregate repositories might be impacted by one event
                this.stagedAggregates.Add(aggregate);
                break;
            }

            return(applicationResult);
        }