/// <summary> /// Create a delegate from an asynchronous (non-cancellable) action. /// </summary> /// <typeparam name="TAttributed">Type of object that contains methods marked with [QueryHandler].</typeparam> /// <typeparam name="TQuery">Type of query that is handled by the QueryHandlerDelegate.</typeparam> /// <typeparam name="TResult">Query's result type.</typeparam> /// <param name="attributedObjectFactory">Factory delegate which produces an instance of <typeparamref name="TAttributed"/>.</param> /// <returns>Instance of QueryHandlerDelegate.</returns> private QueryHandlerDelegate <TResult> createNonCancellableAsyncDelegate <TAttributed, TQuery, TResult>(Func <TAttributed> attributedObjectFactory) where TAttributed : class where TQuery : class, IQuery <TResult> { Func <TAttributed, TQuery, Task <TResult> > asyncFunc = (Func <TAttributed, TQuery, Task <TResult> >)MethodInfo.CreateDelegate(typeof(Func <TAttributed, TQuery, Task <TResult> >)); return(QueryHandlerDelegateBuilder.FromDelegate(attributedObjectFactory, asyncFunc)); }
/// <summary> /// Create a delegate from a synchronous action. /// </summary> /// <typeparam name="TAttributed">Type of object that contains methods marked with [QueryHandler].</typeparam> /// <typeparam name="TQuery">Type of query that is handled by the QueryHandlerDelegate.</typeparam> /// <typeparam name="TResult">Query's result type.</typeparam> /// <param name="attributedObjectFactory">Factory delegate which produces an instance of <typeparamref name="TAttributed"/>.</param> /// <returns>Instance of QueryHandlerDelegate.</returns> private QueryHandlerDelegate <TResult> createWrappedSyncDelegate <TAttributed, TQuery, TResult>(Func <TAttributed> attributedObjectFactory) where TAttributed : class where TQuery : class, IQuery <TResult> { Func <TAttributed, TQuery, TResult> func = (Func <TAttributed, TQuery, TResult>)MethodInfo.CreateDelegate(typeof(Func <TAttributed, TQuery, TResult>)); return(QueryHandlerDelegateBuilder.FromDelegate(attributedObjectFactory, func)); }
/// <summary> /// <para>Resolves an instance of IQueryAsyncHandler<TQuery, TResult> from the container</para> /// <para>and converts it to a query handler delegate which can be invoked to process the query.</para> /// </summary> /// <typeparam name="TQuery">Type of query which is handled by the query handler.</typeparam> /// <typeparam name="TResult">Type of query's result.</typeparam> /// <returns>Instance of <see cref="QueryHandlerDelegate{TResult}"/> which executes the query handler processing.</returns> public QueryHandlerDelegate <TResult> ResolveQueryHandler <TQuery, TResult>() where TQuery : class, IQuery <TResult> { try { IQueryAsyncHandler <TQuery, TResult> queryAsyncHandler = _containerAdapter.Resolve <IQueryAsyncHandler <TQuery, TResult> >(); if (queryAsyncHandler == null) { // No handlers are resolved. Throw exception. throw ExceptionBuilder.NoQueryHandlerResolvedException(typeof(TQuery)); } return(QueryHandlerDelegateBuilder.FromQueryHandler(queryAsyncHandler)); } catch (Exception ex) { // No handlers are resolved. Throw exception. throw ExceptionBuilder.NoQueryHandlerResolvedException(typeof(TQuery), ex); } }
/// <summary> /// Register query async handler. /// </summary> /// <typeparam name="TQuery">Type of query to be handled.</typeparam> /// <typeparam name="TResult">Type of query's result.</typeparam> /// <param name="queryAsyncHandlerFactory">Factory which will provide an instance of a query handler that handles the specified <typeparamref name="TQuery"/> query.</param> public void Register <TQuery, TResult>(Func <IQueryAsyncHandler <TQuery, TResult> > queryAsyncHandlerFactory) where TQuery : class, IQuery <TResult> { if (queryAsyncHandlerFactory == null) { throw new ArgumentNullException(nameof(queryAsyncHandlerFactory)); } Type queryType = typeof(TQuery); QueryHandlerDelegate <TResult> handleQueryDelegate; if (_queryHandlerDelegatesByQueryType.TryGetValue(queryType, out handleQueryDelegate)) { throw new InvalidOperationException($"Duplicate query handler registered for {queryType.Name}."); } QueryHandlerDelegate <TResult> newHandleQueryDelegate = QueryHandlerDelegateBuilder.FromFactory(queryAsyncHandlerFactory); _queryHandlerDelegatesByQueryType.Add(queryType, newHandleQueryDelegate); }