检查 IoC 注册是否实现命令或查询接口,并返回通用参数

Checking if IoC registrations implement command or query interfaces, and returning the generic parameter

我正在使用 SimpleInjector IoC 容器并尝试在应用程序启动时连接功能(容器将报告它已注册的命令处理程序和查询处理程序,我们将注册命令和查询被注册为通用类型):

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());
    }
}

虽然注册返回正确,但我似乎无法:

  1. 检查是否是实现ICommandHandler<SetUserStatusToVerifiedCommand>

  2. 的类型
  3. 如果是,获取通用参数以便我们可以跟踪我们支持的命令

例如,当我在返回的类型为SetUserStatusToVerifiedCommandHandler的注册上断点时,isCommandHandler变量始终为false并且类型字符串显示为:

{Name = "ICommandHandler`1" FullName = "MyApp.ICommandHandler`1[[MyApp.Application.UserStatus.SetUserStatusToVerifiedCommand, MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}`

我的接口和命令处理程序实现为:

public interface ICommand
{
}

class SetUserStatusToVerifiedCommand : ICommand
{
    string UserId;
    DateTime VerifiedOn;
}

class SetUserStatusToVerifiedCommandHandler : ICommandHandler<SetUserStatusToVerifiedCommand>
{
    public void Handle(SetUserStatusToVerifiedCommand commandToHandle)
    {
    }
}

请问我做错了什么?

作为旁注,如果有任何更简单的方法可以通过 SimpleInjector 建议实现上述目标,我们将不胜感激。

问题出在这条语句中:

var type = registration.ServiceType;
var isCommandHandler = type.GetInterfaces().Any(x => x.IsGenericType 
    && x.GetGenericTypeDefinition() == typeof(ICommandHandler<>));

Type.GetInterfaces()方法return是某种类型实现的所有接口的列表。但是 registration.ServiceType 将是 ICommandHandler<T> 的封闭通用版本。所以你基本上是在问 ICommandHandler<T> 实现了什么接口。如果在该接口上调用,GetInterfaces() 将不会 return 接口本身。

因此,您需要这样做:

var type = registration.ServiceType;

var isCommandHandler = type.IsGenericType && 
    type.GetGenericTypeDefinition() == typeof(ICommandHandler<>));