如何在DI容器中按类型注册通用接口

时间:2018-12-25 09:49:15

标签: asp.net-core dependency-injection

我想注册一些可以解析为其相关实现类的通用接口。我正在使用asp.net核心的内置依赖项注入( ServiceProvider )。

假设我的界面是这样的:

public interface ICommandHandler<in TCommand> where TCommand :Command
{
    void Execute(TCommand command);
}

和我的班级是这样的:

public class AddItem1CommandHandler : ICommandHandler<AddItem1Command>

public class AddItem2CommandHandler : ICommandHandler<AddItem2Command>

我的命令显然在接口约束中是这样的:

public class AddItem1Command: Command
public class AddItem2Command: Command

因此,我可以一个一个地注册它们:

services.AddTransient<ICommandHandler<AddItem1Command>, AddItem1CommandHandler>();
services.AddTransient<ICommandHandler<AddItem2Command>, AddItem2CommandHandler>();

这里的问题是我被迫为每个实现定义一个注册。现在我的问题是,有什么办法可以像这样在一行中注册所有人:

services.AddScoped<ICommandHandler<Command>, Command>();

我不知道使用ServiceCollection怎么可能。

1 个答案:

答案 0 :(得分:1)

ICommandHandler<>是通用类型,我从Assembly获得所有实现。

public static void Register(Assembly assembly, IServiceCollection services)
{        
    var allCommandHandler = assembly.GetTypes().Where(t =>
        t.IsClass &&
        !t.IsAbstract &&
        t.IsAssignableToGenericType(typeof(ICommandHandler<>)));
    foreach (var type in allCommandHandler)
    {
        var allInterfaces = type.GetInterfaces();
        var mainInterfaces = allInterfaces.Where(t => t.IsAssignableToGenericType(typeof(ICommandHandler<>)));
        foreach (var itype in mainInterfaces)
        {
            services.AddScoped(itype, type);
        }
    }
}

我在包含dll的{​​{1}}中称这个方法