CQRS with dependency injection
This should be a very quick question. I am trying to learn the CQRS pattern and there is one thing that is not clear. There are two dispatchers: for commands and requests. In order to get the appropriate handler, they need to install the DI core. For example:
var handler = _resolver.Resolve<IQueryHandler<TQuery, TResult>>();
Doesn't that violate the DI concept that Decide should never be used and everything should be injected by the constructor / properties?
There is a larger example: http://www.adamtibi.net/06-2013/implementing-a-cqrs-based-architecture-with-mvc-and-document-db
Please check out this method:
public void Dispatch<TParameter>(TParameter command) where TParameter : ICommand
{
var handler = _kernel.Get<ICommandHandler<TParameter>>();
handler.Execute(command);
}
I found this solution on three different pages. Why is this done instead of creating a factory to map the QueryHandler?
source to share
If you consider the dispatcher to be part of the infrastructure, calling Resolve () within it does not violate the DI concept you described.
Handlers are usually thought of as entry points for logical pipelines (or threads, or you want to think about them nonetheless). This is similar to controllers in MVC or the Main () method in a console application. Thus, like other constructs, the dispatcher is considered the top-level object in the dependency chain and therefore is a perfectly legal place to refer to the container.
Edit
So, the comments mention Composition Root (CR), which is a term I like but deliberately tried to avoid in this answer as it tends to confuse people. Is CR a specific class? Assembly? I tend to think of it as a concept rather than a specific design. This is the logical place in the application where object graphs are composed.
To clarify what I meant for controllers: controllers will be the entry point, and (as @Zbigniew pointed out) the factory controller will be (part of) CR. Likewise, the handlers will be the entry point, and the dispatcher will be the CR. Handlers / Controllers would not have a container reference, but Dispatcher / ControllerFactory.
source to share