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

AddScoped注入时如何调用正确构造函数确保类默认配置生效?

问题解答

两种注册写法效果不一致,核心差异来自ASP.NET Core内置DI的构造函数选择逻辑

  • 第一种写法 services.AddScoped<IHtmlSanitizer, HtmlSanitizer>() 的执行逻辑:
    内置DI容器会自动扫描目标类型HtmlSanitizer的所有公开构造函数,优先选择参数数量最多、且所有参数都能从当前DI容器中获取到实例的构造函数来创建对象,而非默认使用无参构造。
    以你使用的HtmlSanitizer为例,该类存在多个公开构造函数,其中包含接收HtmlSanitizerOptions参数的重载,如果你的项目中恰好注册了该Options类型但没有填充默认配置,DI会直接选择这个带参构造,传入未赋值的Options实例,最终导致实例的配置字段为空。
  • 第二种工厂写法的执行逻辑:
    你在工厂委托中显式调用了无参构造函数new HtmlSanitizer(),完全跳过了DI的构造函数自动选择逻辑,直接执行无参构造中内置的默认配置填充逻辑,因此得到的实例字段是符合预期的非空默认值。

固定参数传参的最佳实践

工厂写法是传入固定参数的推荐方案之一,优势是实例化逻辑完全可控,你可以直接在工厂委托中自定义构造参数:

services.AddScoped<IHtmlSanitizer, HtmlSanitizer>(_ => 
{
    // 自定义配置参数
    var customOptions = new HtmlSanitizerOptions { /* 你的自定义配置 */ };
    return new HtmlSanitizer(customOptions);
});

如果不想用工厂写法,也可以通过配置Options的方式适配第一种注册逻辑:

// 先配置默认的HtmlSanitizerOptions
services.Configure<HtmlSanitizerOptions>(opt =>
{
    // 填充默认配置值
});
// 再注册服务,DI会自动传入配置好的Options
services.AddScoped<IHtmlSanitizer, HtmlSanitizer>();

通用注意事项

该问题不限于HtmlSanitizer库,所有.NET Core/.NET 5+的内置DI场景都适用:当你注册的服务存在多个公开构造函数时,一定要确认DI选择的构造函数是否符合你的预期,如果需要指定构造逻辑,优先用工厂写法显式控制实例化过程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 03:36:03