public async Task <TResult> Dispatch <TResult>(IQuery <TResult> query, CancellationToken cancellationToken = default) { if (query == null) { throw new ArgumentNullException(nameof(query), "Query to dispatch can't be null."); } if (cancellationToken == null) { throw new ArgumentNullException(nameof(cancellationToken), "Cancellation token can't be null."); } QueryDispatchInfo dispatchInfo = _dispatchModule.GetQueryDispatchInfo(query.GetType()); try { await InvokeDispatcher(dispatchInfo, query, cancellationToken).ConfigureAwait(false); } catch (QueryDispatchException ex) { // Log the details of the dispatch exception and rethrow. _logger.LogErrorDetails(MessagingLogEvents.MessagingException, ex, "Exception dispatching query."); throw; } catch (Exception ex) { _logger.LogError(MessagingLogEvents.MessagingException, ex, "Unexpected Exception dispatching query."); throw; } return(query.Result); }
// Creates an instance of the consumer that will execute the query and calls it between the // pre and post filters. private async Task InvokeDispatcher(QueryDispatchInfo dispatcher, IQuery query, CancellationToken cancellationToken) { var consumer = (IQueryConsumer)_services.GetRequiredService(dispatcher.ConsumerType); var configuredFilters = _filterModule.QueryFilterTypes.Select(ft => _services.GetRequiredService(ft)) .Cast <IQueryFilter>() .ToArray(); LogQueryDispatch(query, consumer); await ApplyFilters <IPreQueryFilter>(query, configuredFilters, (f, q) => f.OnPreExecute(q)); await dispatcher.Dispatch(query, consumer, cancellationToken); await ApplyFilters <IPostQueryFilter>(query, configuredFilters, (f, q) => f.OnPostExecute(q)); }