I am using the SimpleInjector IoC container and trying to wire-up functionality on application start-up (the container will report what command-handlers and query-handlers it has registered, and we will register the commands and queries that were registered as generic types):
var suppportedCommands = new List<Type>();
var container = Bootstrapper.SimpleInjectorContainer;
foreach (var registration in container.GetCurrentRegistrations())
{
var type = registration.ServiceType;
var isCommandHandler = type.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICommandHandler<>));
if (isCommandHandler )
{
suppportedCommands.Add(type.GetGenericArguments().First());
}
}
Although the registrations are returned correctly I don't seem to be able to:
Check if it is type that implements ICommandHandler<SetUserStatusToVerifiedCommand>
If it is, get the generic argument so we can keep track of commands we support
As an example, when I break-point on the returned registration that has the type SetUserStatusToVerifiedCommandHandler
, the isCommandHandler variable is always false and the type string is shown as:
{Name = "ICommandHandler`1" FullName = "MyApp.ICommandHandler`1[[MyApp.Application.UserStatus.SetUserStatusToVerifiedCommand, MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}`
And my interfaces and command handlers implemented as:
public interface ICommand
{
}
class SetUserStatusToVerifiedCommand : ICommand
{
string UserId;
DateTime VerifiedOn;
}
class SetUserStatusToVerifiedCommandHandler : ICommandHandler<SetUserStatusToVerifiedCommand>
{
public void Handle(SetUserStatusToVerifiedCommand commandToHandle)
{
}
}
Any ideas what I am doing wrong please?
As a sidenote, if there is any simpler way to achieve the above with SimpleInjector advice would be appreciated.
The problem is in this statement:
var type = registration.ServiceType;
var isCommandHandler = type.GetInterfaces().Any(x => x.IsGenericType
&& x.GetGenericTypeDefinition() == typeof(ICommandHandler<>));
The Type.GetInterfaces()
method returns the list of all interfaces that a certain type implements. But the registration.ServiceType
will be a closed-generic version of ICommandHandler<T>
. So you are basically asking what interfaces ICommandHandler<T>
implements. And GetInterfaces()
will not return the interface itself if called on that interface.
So instead, you need to do this:
var type = registration.ServiceType;
var isCommandHandler = type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(ICommandHandler<>));