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

C# DI容器注入含非已注册构造参数类的配置方法

正确注册实现方式

你使用显式工厂委托注册时,委托入参sp是当前DI容器的服务提供实例,可直接从该实例解析出已注册的IHttpClientFactory,再手动传入你自定义的s1、s2实际值即可,完整写法如下:

// 替换为你业务中s1、s2需要的实际值,也可从配置文件读取
string customS1 = "第一个字符串参数的实际业务值";
string customS2 = "第二个字符串参数的实际业务值";

services.AddScoped<IInterface>(sp =>
{
    // 从容器中解析已注册的IHttpClientFactory依赖
    var httpClientFactory = sp.GetRequiredService<IHttpClientFactory>();
    // 传入全部构造参数完成实例化
    return new Concrete(httpClientFactory, customS1, customS2);
});

注意事项

  • 推荐使用GetRequiredService<T>()解析容器内已注册的依赖:如果依赖因配置缺失无法解析,该方法会立刻抛出明确的异常,比GetService<T>()返回null后触发空引用问题更易排错。
  • 你之前参考的写法services.AddScoped<IInterface, Concrete>(sp => {})中第二个泛型参数Concrete属于冗余写法,因为你已经在工厂委托中手动创建了Concrete实例,省略该泛型参数即可,保留也不会引发运行错误。
  • 如果你的s1、s2值来自配置文件,可在注册阶段直接从IConfiguration实例读取对应配置项后传入,无需将字符串本身注册到DI容器。

可选优化方案

如果你定义的Concrete类全程只使用你之前注册的名为clientName的HttpClient,不需要动态创建其他命名客户端,可以直接调整构造函数依赖为HttpClient,注册时直接解析对应命名客户端传入,省掉类内部手动调用CreateClient的步骤:

// 调整后类构造示例
public class Concrete : IInterface
{
    private readonly HttpClient _client;
    private readonly string _s1;
    private readonly string _s2;

    public Concrete(HttpClient client, string s1, string s2)
    {
        _client = client;
        _s1 = s1;
        _s2 = s2;
    }
}

// 对应注册写法
services.AddScoped<IInterface>(sp =>
{
    var httpClientFactory = sp.GetRequiredService<IHttpClientFactory>();
    var namedClient = httpClientFactory.CreateClient("clientName");
    return new Concrete(namedClient, customS1, customS2);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 14:45:32