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

能否在.NET Core原生DI容器中实现类似Ninject的命名绑定?

.NET Core原生DI实现类似Ninject的命名绑定

.NET Core原生DI容器本身并没有内置像Ninject那样直接的命名绑定功能,但咱们可以通过几种实用的方式来实现类似的效果,满足你根据名称获取IValidationRule不同实现的需求。

方案一:自定义服务工厂(兼容所有.NET Core版本)

这种方式适用于所有.NET Core版本,核心思路是通过一个工厂类来管理不同实现的名称映射,然后从容器中获取对应的实例。

步骤1:定义工厂接口

public interface IValidationRuleFactory
{
    IValidationRule GetRule(string ruleName);
}

步骤2:实现工厂类

在工厂类中维护名称与实现类的映射,同时注入IServiceProvider来获取实例:

public class ValidationRuleFactory : IValidationRuleFactory
{
    private readonly IServiceProvider _serviceProvider;
    private readonly Dictionary<string, Type> _ruleTypeMap = new()
    {
        {"first", typeof(FirstValidationRule)},
        {"second", typeof(SecondValidationRule)}
    };

    public ValidationRuleFactory(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public IValidationRule GetRule(string ruleName)
    {
        if (_ruleTypeMap.TryGetValue(ruleName, out var ruleType))
        {
            return (IValidationRule)_serviceProvider.GetRequiredService(ruleType);
        }
        throw new ArgumentException($"找不到名称为「{ruleName}」的验证规则");
    }
}

步骤3:注册服务

先注册所有的IValidationRule实现类,再注册工厂:

services.AddSingleton<FirstValidationRule>();
services.AddSingleton<SecondValidationRule>();
services.AddSingleton<IValidationRuleFactory, ValidationRuleFactory>();

步骤4:使用工厂获取实例

var ruleFactory = provider.GetRequiredService<IValidationRuleFactory>();
var firstRule = ruleFactory.GetRule("first"); // 获取FirstValidationRule实例
var secondRule = ruleFactory.GetRule("second"); // 获取SecondValidationRule实例

方案二:使用键服务注入(.NET 8及以上版本)

从.NET 8开始,原生DI新增了**键服务(Keyed Services)**功能,这是官方提供的类似命名绑定的解决方案,用法更简洁。

步骤1:注册键服务

直接通过AddKeyedSingleton(或对应的生命周期方法)注册带名称(键)的服务:

// .NET 8+ 专属语法
services.AddKeyedSingleton<IValidationRule, FirstValidationRule>("first");
services.AddKeyedSingleton<IValidationRule, SecondValidationRule>("second");

步骤2:获取指定键的服务

可以直接通过GetRequiredKeyedService方法按键获取实例:

var firstRule = provider.GetRequiredKeyedService<IValidationRule>("first");
var secondRule = provider.GetRequiredKeyedService<IValidationRule>("second");

如果需要在构造函数中注入指定键的服务,可以使用[FromKeyedServices]特性:

public class SomeService
{
    public SomeService([FromKeyedServices("first")] IValidationRule firstRule)
    {
        // 使用firstRule
    }
}

补充说明

原生DI的设计理念更偏向于显式依赖注入,即通过构造函数明确声明所需的依赖,而不是动态根据名称获取。但上述两种方式都能很好地模拟命名绑定的场景,你可以根据项目的.NET版本选择合适的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:57:16