Example #1
0
        private QueryHandlerWrapper <TResponse> GetWrappedHandlers <TResponse>(IQueryRequest <TResponse> query)
        {
            Type[] typeArgs = { query.GetType(), typeof(TResponse) };

            var handlerType = typeof(IQueryRequestHandler <,>).MakeGenericType(typeArgs);
            var wrapperType = typeof(QueryHandlerWrapper <,>).MakeGenericType(typeArgs);

            var handlers =
                (IEnumerable)_serviceProvider.GetRequiredService(typeof(IEnumerable <>).MakeGenericType(handlerType));

            var wrappedHandlers = (QueryHandlerWrapper <TResponse>)QueryHandlers.GetOrAdd(query.GetType(), handlers.Cast <object>()
                                                                                          .Select(_ => (QueryHandlerWrapper <TResponse>)Activator.CreateInstance(wrapperType)).FirstOrDefault());

            return(wrappedHandlers);
        }
Example #2
0
        public TResponse Execute <TResponse>(IQueryRequest <TResponse> request)
            where TResponse : IQueryResponse
        {
            var requestType = request.GetType();

            _logger.InfoFormat("Building and executing pipeline for {RequestType}", requestType.Name);

            // todo: c# 7 tuples to the rescue pls!
            var deconstructMe = ResolveHandler(requestType);
            var handlerType   = deconstructMe.Item1;
            var handler       = deconstructMe.Item2;

            var requestContext = CreateRequestContext();

            handler.Context = requestContext;

            var decorators = GetDecorators <TResponse>(handlerType.GetMethod(nameof(IQueryHandler <IQueryRequest <TResponse>, TResponse> .Execute)), requestContext);

            _logger.Debug("Begin building pipeline...");

            var pipeline = new List <Func <IQueryRequest <TResponse>, TResponse> >
            {
                r => handler.Execute((dynamic)r)
            };

            // fallback is doesn't have an incoming pipeline
            Func <IQueryRequest <TResponse>, TResponse> fallback = r => handler.Fallback((dynamic)r);

            foreach (var decorator in decorators)
            {
                _logger.DebugFormat("Adding decorator to pipeline: {Decorator}", decorator.GetType().Name);

                var next = pipeline.Last();
                pipeline.Add(r => decorator.Execute(r, next, fallback));
            }

            try
            {
                _logger.DebugFormat("Invoking pipeline...");
                return(pipeline.Last().Invoke(request));
            }
            catch (Exception ex)
            {
                _logger.InfoException("An exception was thrown during pipeline execution", ex);
                throw;
            }
        }
Example #3
0
        public async Task <TResponse> ExecuteAsync <TResponse>(IQueryRequest <TResponse> request, CancellationToken cancellationToken = default(CancellationToken))
            where TResponse : IQueryResponse
        {
            var requestType = request.GetType();

            _logger.InfoFormat("Building and executing async pipeline for {RequestType}", requestType.Name);

            // todo: c# 7 tuples to the rescue pls!
            var deconstructMe = ResolveHandler(requestType);
            var handlerType   = deconstructMe.Item1;
            var handler       = deconstructMe.Item2;

            var requestContext = CreateRequestContext();

            handler.Context = requestContext;

            var decorators = GetDecorators <TResponse>(handlerType.GetMethod(nameof(IQueryHandler <IQueryRequest <TResponse>, TResponse> .ExecuteAsync)), requestContext);

            _logger.Debug("Begin building async pipeline...");

            var pipeline = new List <Func <IQueryRequest <TResponse>, CancellationToken, Task <TResponse> > >
            {
                (r, ct) => handler.ExecuteAsync((dynamic)r, ct)
            };

            // fallback is doesn't have an incoming pipeline
            Func <IQueryRequest <TResponse>, CancellationToken, Task <TResponse> > fallback = (r, ct) => handler.FallbackAsync((dynamic)r, ct);

            foreach (var decorator in decorators)
            {
                _logger.DebugFormat("Adding decorator to async pipeline: {Decorator}", decorator.GetType().Name);

                var next = pipeline.Last();
                pipeline.Add((r, ct) => decorator.ExecuteAsync(r, next, fallback, ct));
            }

            try
            {
                _logger.DebugFormat("Invoking async pipeline...");
                return(await pipeline.Last().Invoke(request, cancellationToken).ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                _logger.InfoException("An exception was thrown during async pipeline execution", ex);
                throw;
            }
        }