首页 > 解决方案 > 如何在 DI 容器中按类型注册通用接口

问题描述

我想注册一些可以解析为相关实现类的通用接口。我正在使用 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 怎么可能。

标签: asp.net-coredependency-injection

解决方案


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包含中调用此方法CommandHandler


推荐阅读