You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6中如何通过依赖注入注册并检索任意数量的类?

解决方案

1. 确定统一的处理器接口

优先选择非泛型接口方案,泛型接口会导致每个处理器的接口类型不一致,大幅增加DI注册和字典构建的复杂度。修正后的接口定义如下:

public interface IColorHandler
{
    // 只读属性,标识当前处理器负责的枚举值
    Color HandledColor { get; }
    Task<string> GetContent(GeneralParamsObject info);
}

2. 实现具体处理器类

每个处理器类只需实现上述接口,并明确指定对应的HandledColor:

public class GreenHandler : IColorHandler
{
    public Color HandledColor => Color.Green;

    public Task<string> GetContent(GeneralParamsObject info)
    {
        // 编写对应颜色的业务逻辑
        return Task.FromResult("针对绿色的内容");
    }
}

// 其他颜色处理器同理,比如BlueHandler、RedHandler等

3. 依赖注入注册配置

分两步完成注册:先扫描并注册所有处理器,再构建并注册字典:

第一步:扫描注册所有处理器

沿用你现有的扫描方式,将所有实现IColorHandler的类注册为Scoped生命周期:

serviceCollection.Scan(scan => scan
    .FromAssemblies(AppDomain.CurrentDomain.GetAssemblies())
    .AddClasses(classes => classes.AssignableTo<IColorHandler>())
    .As<IColorHandler>()
    .WithScopedLifetime());

第二步:注册字典实例

通过工厂方式,从DI容器中获取所有处理器实例,转换为以枚举为键的字典,同时添加重复键校验提前暴露问题:

serviceCollection.AddScoped<IDictionary<Color, IColorHandler>>(sp =>
{
    var allHandlers = sp.GetServices<IColorHandler>();

    // 校验是否存在重复的枚举处理器
    var duplicateHandlers = allHandlers
        .GroupBy(handler => handler.HandledColor)
        .Where(group => group.Count() > 1)
        .Select(group => group.Key);

    if (duplicateHandlers.Any())
    {
        throw new InvalidOperationException($"存在重复的颜色处理器,枚举值:{string.Join(", ", duplicateHandlers)}");
    }

    return allHandlers.ToDictionary(handler => handler.HandledColor);
});

4. 主服务使用字典

你的ColorContentService代码无需修改,直接注入字典即可使用:

public class ColorContentService : IColorContentService
{
    private readonly IDictionary<Color, IColorHandler> _handlers;
    
    public ColorContentService(IDictionary<Color, IColorHandler> handlers)
    {
        _handlers = handlers;
    }
    
    public async Task<string> GetColorsContent(List<Color> colors)
    {
        var info = BuildInfoObject();
        var content = new StringBuilder();
        foreach (var color in colors)
        {
            if (_handlers.TryGetValue(color, out var handler))
            {
                content.AppendLine(await handler.GetContent(info));
            }
        }
        return content.ToString();
    }

    private GeneralParamsObject BuildInfoObject()
    {
        // 构建参数对象的逻辑
        return new GeneralParamsObject();
    }
}

关键说明

  • 生命周期匹配:字典和处理器都使用Scoped生命周期,确保每次请求中处理器的实例一致性
  • 性能优化:字典的TryGetValue是O(1)操作,远快于遍历IEnumerable的O(n),适合百级数量的处理器场景
  • 兼容性:所有API均支持.NET 6,无需使用后续版本的新特性

内容的提问来源于stack exchange,提问作者Sabelyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 19:32:34