public async Task <ActionResult> UpdateserviceListItemAsync([FromBody] ServiceListItem serviceListItemToUpdate) { var ServiceListItem = await _serviceListContext.ServiceListItems.SingleOrDefaultAsync(i => i.Id == serviceListItemToUpdate.Id); if (ServiceListItem == null) { return(NotFound(new { Message = $"Item with id {serviceListItemToUpdate.Id} not found." })); } var oldPrice = ServiceListItem.Price; var raiseserviceListItemPriceChangedEvent = oldPrice != serviceListItemToUpdate.Price; // Update current serviceListItem ServiceListItem = serviceListItemToUpdate; _serviceListContext.ServiceListItems.Update(ServiceListItem); if (raiseserviceListItemPriceChangedEvent) // Save serviceListItem's data and publish integration event through the Event Bus if price has changed { //Create Integration Event to be published through the Event Bus var priceChangedEvent = new ServiceListPriceChangedIntegrationEvent(ServiceListItem.Id, serviceListItemToUpdate.Price, oldPrice); // Achieving atomicity between original Catalog database operation and the IntegrationEventLog thanks to a local transaction await _catalogIntegrationEventService.SaveEventAndServiceListContextChangesAsync(priceChangedEvent); // Publish through the Event Bus and mark the saved event as published await _catalogIntegrationEventService.PublishThroughEventBusAsync(priceChangedEvent); } else // Just save the updated serviceListItem because the serviceListItem's Price hasn't changed. { await _serviceListContext.SaveChangesAsync(); } return(CreatedAtAction(nameof(ItemByIdAsync), new { id = serviceListItemToUpdate.Id }, null)); }
public async Task Handle(ServiceListPriceChangedIntegrationEvent @event) { using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); var serviceListItem = _serviceListContext.ServiceListItems.Where(l => l.Id == @event.ServiceListId).FirstOrDefault(); serviceListItem.PriceAfterDiscount = @event.NewPrice; await _serviceListContext.SaveChangesAsync(); } }
public async Task SaveEventAndServiceListContextChangesAsync(IntegrationEvent evt) { _logger.LogInformation("----- CatalogIntegrationEventService - Saving changes and integrationEvent: {IntegrationEventId}", evt.Id); //Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction(): //See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency await ResilientTransaction.New(_ServiceListContext).ExecuteAsync(async() => { // Achieving atomicity between original catalog database operation and the IntegrationEventLog thanks to a local transaction await _ServiceListContext.SaveChangesAsync(); await _eventLogService.SaveEventAsync(evt, _ServiceListContext.Database.CurrentTransaction); }); }