public async Task UpdateProductAsync(CatalogItem productToUpdate) { //TODO: checking for necessity of publishing event PriceChanged //TODO: Other possibilities for state of event is not considered //To update the price of a product and guarantee consistency, //(that the publishing of it's related event has definitely happened after persisting in current service, //first we need to update CatalogContext(and product) //and we need to store details of the related event in database (IntegrationEventLogContext) //IN THE SAME TRANSACTION //then we will publish the event //and if everything goes as expected, we change the state of event to published in db //TODO don't send productToUpdate to repo. fetch the current object, change it's price then send it (if fetched in admin panel before update there is no problem var oldPrice = _catalogContext.CatalogItems.AsNoTracking().Single(e => e.Id == productToUpdate.Id).Price; if (oldPrice != productToUpdate.Price) { ProductPriceChangedIntegrationEvent evt = new ProductPriceChangedIntegrationEvent(productToUpdate.Id, productToUpdate.Price, oldPrice); using (var transaction = _catalogContext.Database.BeginTransaction()) { _catalogContext.CatalogItems.Update(productToUpdate); await _catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(evt); transaction.Commit(); } _eventBus.Publish(evt); await _integrationEventLogService.MarkEventAsPublished(evt.Id); } else { _catalogContext.CatalogItems.Update(productToUpdate); _catalogContext.SaveChanges(); } }
public async Task PublishThroughEventBusAsync(IntegrationEvent evt) { _eventBus.Publish(evt); _eventLogService.MarkEventAsPublished(evt); }