|
|
@ -2,6 +2,7 @@ |
|
|
|
using Microsoft.EntityFrameworkCore.Storage; |
|
|
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; |
|
|
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; |
|
|
|
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; |
|
|
|
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services; |
|
|
|
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Utilities; |
|
|
|
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; |
|
|
@ -17,12 +18,16 @@ namespace Ordering.API.Application.IntegrationEvents |
|
|
|
private readonly Func<DbConnection, IIntegrationEventLogService> _integrationEventLogServiceFactory; |
|
|
|
private readonly IEventBus _eventBus; |
|
|
|
private readonly OrderingContext _orderingContext; |
|
|
|
private readonly IntegrationEventLogContext _eventLogContext; |
|
|
|
private readonly IIntegrationEventLogService _eventLogService; |
|
|
|
|
|
|
|
public OrderingIntegrationEventService(IEventBus eventBus, OrderingContext orderingContext, |
|
|
|
Func<DbConnection, IIntegrationEventLogService> integrationEventLogServiceFactory) |
|
|
|
public OrderingIntegrationEventService(IEventBus eventBus, |
|
|
|
OrderingContext orderingContext, |
|
|
|
IntegrationEventLogContext eventLogContext, |
|
|
|
Func<DbConnection, IIntegrationEventLogService> integrationEventLogServiceFactory) |
|
|
|
{ |
|
|
|
_orderingContext = orderingContext ?? throw new ArgumentNullException(nameof(orderingContext)); |
|
|
|
_eventLogContext = eventLogContext ?? throw new ArgumentNullException(nameof(eventLogContext)); |
|
|
|
_integrationEventLogServiceFactory = integrationEventLogServiceFactory ?? throw new ArgumentNullException(nameof(integrationEventLogServiceFactory)); |
|
|
|
_eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus)); |
|
|
|
_eventLogService = _integrationEventLogServiceFactory(_orderingContext.Database.GetDbConnection()); |
|
|
@ -37,14 +42,8 @@ namespace Ordering.API.Application.IntegrationEvents |
|
|
|
|
|
|
|
private async Task SaveEventAndOrderingContextChangesAsync(IntegrationEvent evt) |
|
|
|
{ |
|
|
|
//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(_orderingContext) |
|
|
|
.ExecuteAsync(async () => { |
|
|
|
// Achieving atomicity between original ordering database operation and the IntegrationEventLog thanks to a local transaction
|
|
|
|
await _orderingContext.SaveChangesAsync(); |
|
|
|
await _eventLogService.SaveEventAsync(evt, _orderingContext.Database.CurrentTransaction.GetDbTransaction()); |
|
|
|
}); |
|
|
|
await _orderingContext.SaveChangesAsync(); |
|
|
|
await _eventLogContext.SaveChangesAsync(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |