public ISagaQueryScopeContext <TSaga, T> GetQueryScope <T>(SagaQueryConsumeContext <TSaga, T> context) where T : class { if (context.TryGetPayload <IKernel>(out var kernel)) { kernel.UpdateScope(context); return(new ExistingSagaQueryScopeContext <TSaga, T>(context)); } var scope = _kernel.CreateNewOrUseExistingMessageScope(context); try { var proxy = new SagaQueryConsumeContextScope <TSaga, T>(context, context.Query, _kernel); foreach (Action <ConsumeContext> scopeAction in _scopeActions) { scopeAction(proxy); } return(new CreatedSagaQueryScopeContext <IDisposable, TSaga, T>(scope, proxy)); } catch { scope.Dispose(); throw; } }
async Task IFilter <ConsumeContext <TMessage> > .Send(ConsumeContext <TMessage> context, IPipe <ConsumeContext <TMessage> > next) { Stopwatch timer = Stopwatch.StartNew(); var activity = LogContext.IfEnabled(OperationName.Saga.SendQuery)?.StartActivity(new { SagaType = TypeMetadataCache <TSaga> .ShortName, MessageType = TypeMetadataCache <TMessage> .ShortName }); try { ISagaQuery <TSaga> query = _queryFactory.CreateQuery(context); SagaQueryConsumeContext <TSaga, TMessage> queryContext = new SagaQueryConsumeContextScope <TSaga, TMessage>(context, query); await Task.Yield(); await _sagaRepository.SendQuery(queryContext, _policy, _messagePipe).ConfigureAwait(false); await next.Send(context).ConfigureAwait(false); await context.NotifyConsumed(timer.Elapsed, TypeMetadataCache <TSaga> .ShortName).ConfigureAwait(false); } catch (OperationCanceledException exception) { await context.NotifyFaulted(timer.Elapsed, TypeMetadataCache <TSaga> .ShortName, exception).ConfigureAwait(false); if (exception.CancellationToken == context.CancellationToken) { throw; } throw new ConsumerCanceledException($"The operation was cancelled by the consumer: {TypeMetadataCache<TSaga>.ShortName}"); } catch (Exception ex) { await context.NotifyFaulted(timer.Elapsed, TypeMetadataCache <TSaga> .ShortName, ex).ConfigureAwait(false); throw; } finally { activity?.Stop(); } }
ISagaQueryScopeContext <TSaga, T> ISagaScopeProvider <TSaga> .GetQueryScope <T>(SagaQueryConsumeContext <TSaga, T> context) { if (context.TryGetPayload <IUnityContainer>(out var existingScope)) { return(new ExistingSagaQueryScopeContext <TSaga, T>(context)); } var scope = _container.CreateChildContainer(); try { var proxy = new SagaQueryConsumeContextScope <TSaga, T>(context, context.Query, scope); return(new CreatedSagaQueryScopeContext <IUnityContainer, TSaga, T>(scope, proxy)); } catch { scope.Dispose(); throw; } }