I have a couple of interfaces that are used to notify request objects and request handlers: -
public interface IQuery<TResponse> { }
public interface IQueryBus
{
public TResponse Resolve<TResponse>(IQuery<TResponse> query);
}
It should be called in the controller layer as follows: -
FooQuery query = ... // comes from model binding
FooResponse response = this.bus.Resolve(query);
The bus is responsible for finding the request handler: -
public interface IQueryHandler<in TQuery, out TResponse>
where TQuery : IQuery<TResponse>
{
public TResponse Handle(TQuery query);
}
Handlers are connected using a dependent converter (I use Ninject, but this should not make much difference).
My current implementation runs in the following lines: -
public TResponse Resolve(IQuery<TResponse> query)
{
var queryType = query.GetType();
var handlerType = typeof(IQueryHandler<,>)
.MakeGenericType(queryType, typeof(TResponse));
var handleMethod = handlerType.GetMethod("Handle", ...);
var handler = kernel.Get(handlerType);
return (TResponse)handleMethod.Invoke(handler, new[] { query });
}
My problem is that I would like to avoid the callMethodInfo.Invoke for stylistic and official purposes.
If I change the signature IQueryBus.Resolveto: -
public TResponse Resolve<TQuery, TResponse>(TQuery query)
where TQuery : IQuery<TResponse>
Then it's pretty simple to change the implementation: -
var handler = kernel.GetType<IQueryHandler<TQuery, TResponse>>();
return handler.Handle(query);
, , : -
FooResponse response = this.bus.Resolve<FooQuery, FooResponse>(query);
? , : -
IQueryBus.Resolve (.. )Query Response Response, Handler (.. )IQueryHandler (.. )
, IQueryBus. , ( , atm).
, , , , , - , .
ShortBus on github, .