2017-04-03 13:13:40 +02:00
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
2017-04-28 15:04:38 +02:00
|
|
|
|
using Microsoft.EntityFrameworkCore.Storage;
|
2017-04-03 13:13:40 +02:00
|
|
|
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
|
|
|
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
|
|
|
|
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
|
|
|
|
|
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Utilities;
|
|
|
|
|
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Data.Common;
|
2017-05-11 13:44:38 +02:00
|
|
|
|
using System.Diagnostics;
|
2017-04-03 13:13:40 +02:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
2017-04-28 14:25:52 +02:00
|
|
|
|
namespace Ordering.API.Application.IntegrationEvents
|
2017-04-03 13:13:40 +02:00
|
|
|
|
{
|
|
|
|
|
public class OrderingIntegrationEventService : IOrderingIntegrationEventService
|
|
|
|
|
{
|
|
|
|
|
private readonly Func<DbConnection, IIntegrationEventLogService> _integrationEventLogServiceFactory;
|
|
|
|
|
private readonly IEventBus _eventBus;
|
|
|
|
|
private readonly OrderingContext _orderingContext;
|
|
|
|
|
private readonly IIntegrationEventLogService _eventLogService;
|
|
|
|
|
|
2017-04-28 14:25:52 +02:00
|
|
|
|
public OrderingIntegrationEventService(IEventBus eventBus, OrderingContext orderingContext,
|
2017-04-03 13:13:40 +02:00
|
|
|
|
Func<DbConnection, IIntegrationEventLogService> integrationEventLogServiceFactory)
|
|
|
|
|
{
|
|
|
|
|
_orderingContext = orderingContext ?? throw new ArgumentNullException(nameof(orderingContext));
|
|
|
|
|
_integrationEventLogServiceFactory = integrationEventLogServiceFactory ?? throw new ArgumentNullException(nameof(integrationEventLogServiceFactory));
|
|
|
|
|
_eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus));
|
|
|
|
|
_eventLogService = _integrationEventLogServiceFactory(_orderingContext.Database.GetDbConnection());
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-05 11:07:26 +02:00
|
|
|
|
public async Task PublishThroughEventBusAsync(IntegrationEvent evt)
|
2017-04-03 13:13:40 +02:00
|
|
|
|
{
|
|
|
|
|
_eventBus.Publish(evt);
|
|
|
|
|
await _eventLogService.MarkEventAsPublishedAsync(evt);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-05 11:07:26 +02:00
|
|
|
|
public async Task SaveEventAndOrderingContextChangesAsync(IntegrationEvent evt)
|
2017-04-03 13:13:40 +02:00
|
|
|
|
{
|
|
|
|
|
//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());
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|