public void SetUp() { _container = new Container(x => x.For(typeof(IEventQueueFactory <>)).Use(typeof(DefaultEventQueueFactory <>))); var services = new StructureMapServiceLocator(_container); _factory = new EventQueueFactory(services); }
private async Task <int> SaveChangesAsync(DbContext context, CancellationToken cancellationToken = default) { Validate.IsNotNull(context); var success = false; var rows = default(int); var aggregates = _context.GetPendingAggregates().ToArray(); await ProcessPreTransactionEvents().ConfigureAwait(false); AzureEfConfiguration.SuspendExecutionStrategy = true; var operation = new Func <Task> ( async() => { using (var transaction = context.Database.BeginTransaction()) { try { rows = await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false); transaction.Commit(); success = true; } catch (Exception ex) { transaction.Rollback(); if (ex is DBConcurrencyException || ex is OptimisticConcurrencyException) { // NOTE: // For concurrency exceptions we want to ensure the // entities are not cached in the context so we can // stop the same error being raised indefinitely. await RefreshAllAsync(cancellationToken).ConfigureAwait(false); } throw; } } } ); await new SqlAzureExecutionStrategy().Execute(operation).ConfigureAwait(false); AzureEfConfiguration.SuspendExecutionStrategy = false; if (success) { await ProcessPostTransactionEvents().ConfigureAwait(false); } async Task ProcessPreTransactionEvents() { IEventQueue CreateQueue() { return(EventQueueFactory.CreatePreTransactionEventQueue(aggregates)); } var eventQueue = CreateQueue(); while (false == eventQueue.IsEmpty()) { var preProcessItems = eventQueue.ToList(); await ProcessEventQueue(eventQueue, true).ConfigureAwait(false); aggregates = _context.GetPendingAggregates().ToArray(); eventQueue = CreateQueue().Remove(preProcessItems); } } async Task ProcessPostTransactionEvents() { var eventQueue = EventQueueFactory.CreatePostTransactionEventQueue(aggregates); foreach (var aggregate in aggregates) { if (aggregate.UnpublishedEvents != null) { aggregate.UnpublishedEvents.Clear(); } } await ProcessEventQueue(eventQueue).ConfigureAwait(false); } return(rows); }