I’m trying to build a command processor that can take any command that implements a marker interface (or maybe descends from a base class). The processor will handle the command that it is asked to process. However I’m struggling with resolving the true generic type as Resolve(Type) returns an object.
I’m not sure is how to cast this if at all possible?
public void Process(ICommand command)
{
var c = command.GetType();
var t = typeof(ICommandHandler<>).MakeGenericType(new[] { c });
var o = container.Resolve(t);
//((ICommandHandler)o).Handle(command); *** This doesn't work
}
The calling code would be something like this –
Dispatcher.Process(new SomeCommand(Guid.NewGuid(),"Param1",12345));
If you absolutely have to call the
ICommandHandler<T>.Handlemethod and you have no other control over the design of the system, then reflection may be your only choice. There’s no great way to deal with the switch from generic to non-generic.Otherwise, you may have a couple of options.
First, if your
Dispatcher.Processcan be made generic, you can save all the casting.This is a pretty common solution to a problem like this that I’ve seen out in the wild.
If you can’t do that, then you may be able to make your
ICommandHandler<T>interface implement a non-genericICommandHandlerbase interface.In this latter case you’d have to switch your strongly-typed command handler implementations to call the same internal logic for generic or basic handling or you’ll get different handling based on the call, which would be bad:
Then when you resolve the strongly-typed
ICommandHandler<T>your cast down toICommandHandler(as shown in your question’s sample code) will work.This is also a pretty common solution, but I’ve seen it more in systems that existed before generics were available where an updated API was being added.
However, in all cases here, the problem really isn’t that Autofac is returning an object; it’s a class/type design problem that affects any generic-to-non-generic conversion scenario.