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

.NET默认DI如何支持C# init关键字修饰属性的依赖注入

核心原因

.NET 内置默认依赖注入(DI)容器仅原生支持构造函数注入、方法参数注入两种注入模式,不会自动解析并为init/普通set属性填充依赖实例,这是容器的设计选择,和init关键字本身不存在兼容性冲突。

首先澄清常见认知误区:init属性并非只能通过对象初始化器赋值。它的访问规则是仅允许在对象初始化阶段(实例构造函数执行过程、对象初始化器表达式)赋值,初始化完成后外部无法修改,和传统readonly私有字段的不可变效果几乎一致,完全可以和构造函数注入搭配使用,不需要更换容器也不需要额外配置。

推荐方案(无额外依赖,兼容默认DI)

直接在构造函数中为init属性赋值即可,比传统私有字段+构造函数赋值的写法更简洁,还保留了依赖不可修改的特性:

// 无需声明单独的私有后备字段,init自动保证注入后属性不会被意外篡改
public IContactsProcessService ContactProcessService { get; init; }

public WebApiController(IContactsProcessService contactProcessService)
{
    // 构造函数属于init允许的赋值阶段,语法完全合法
    ContactProcessService = contactProcessService;
}

这种写法的优势:

  • 完全兼容.NET默认DI机制,不需要引入第三方组件
  • 保留init的不可变特性,服务注入后不会被意外修改,和原有readonly字段效果一致
  • 比传统写法少了私有字段声明、字段逐行赋值的冗余代码,可读性更高
  • 保留构造函数注入的依赖校验优势:容器创建实例时就会检查依赖是否注册,缺失依赖会直接抛出异常,不会出现运行时才触发的空引用问题
可选方案(零构造函数写法)

如果希望完全省略构造函数,直接通过属性注入填充依赖,可以替换默认DI容器为支持属性注入的第三方实现,比如Autofac、DryIoc等,这类容器都支持配置规则,自动为标记为public的init属性注入对应实例。
注意:这种写法存在固有缺陷:属性注入不会在实例创建时强制校验依赖是否存在,若依赖未注册,会在首次调用属性时才抛出空引用异常,排查成本更高,非特殊场景不优先推荐。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 11:01:06