コード例 #1
0
ファイル: StartDeliveryHandler.cs プロジェクト: spetz/NPost
        public async Task HandleAsync(StartDelivery command)
        {
            if (command.Parcels is null)
            {
                throw new Exception("Parcels to be delivered were not specified.");
            }

            var parcels = new HashSet <Parcel>();

            foreach (var parcelId in command.Parcels)
            {
                var parcel = await _parcelsRepository.GetAsync(parcelId);

                if (parcel is null)
                {
                    throw new Exception($"Parcel: {parcelId:N} to be delivered was not found.");
                }

                if (await _deliveriesRepository.HasParcelInDelivery(parcelId))
                {
                    throw new Exception($"Parcel: {parcelId:N} is unavailable.");
                }

                parcels.Add(parcel);
            }

            if (!parcels.Any())
            {
                throw new Exception($"Delivery cannot be started without the parcels.");
            }

            _logger.LogInformation("Calculating the route...");
            var route = await _routingServiceClient.GetAsync(parcels.Select(p => p.Address));

            if (route is null)
            {
                throw new Exception("Route was not found.");
            }

            _logger.LogInformation("Route was calculated.");
            var delivery = new Delivery(command.DeliveryId, parcels.Select(p => p.Id),
                                        new Route(route.Addresses, route.Distance));

            delivery.Start();
            await _deliveriesRepository.AddAsync(delivery);

            _logger.LogInformation($"Started a delivery: {command.DeliveryId:N}");

            var domainEvents = delivery.Events;

            foreach (var domainEvent in domainEvents)
            {
                await _domainEventPublisher.PublishAsync(domainEvent);
            }

            delivery.ClearEvents();

            var events = parcels.Select(p => new DeliveryStarted(command.DeliveryId, p.Id));

            foreach (var @event in events)
            {
                await _dispatcher.PublishAsync(@event);
            }
        }