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

.NET默认DI中TryAddEnumerable在Autofac中的等效实现

.NET默认DI中TryAddEnumerable在Autofac中的等效实现

嘿,我来帮你确认这个等效写法的问题!

首先得先明确你在.NET 7默认DI里那行代码到底做了什么:

services.TryAddEnumerable(ServiceDescriptor.Scoped<CircuitHandler, MyCustomCircuit>());

它核心干了两件事:

  • 给MyCustomCircuit设置了Scoped生命周期,也就是每个请求/作用域内只会创建一个实例
  • 借助TryAddEnumerable的特性:如果这个MyCustomCircuit作为CircuitHandler的实现还没被注册过,才会往服务集合里加——说白了就是避免重复注册同一个实现

再来看你写的Autofac代码:

builder.RegisterType<MyCustomCircuit>().As<CircuitHandler>().InstancePerMatchingLifetimeScope();

这已经非常接近等效实现了,不过有两个细节需要调整或说明:

1. 生命周期的匹配

.NET默认DI里的Scoped,对应Autofac里的.InstancePerLifetimeScope()(这是默认的请求作用域)。而.InstancePerMatchingLifetimeScope()是用来匹配自定义标记的作用域的,如果你没有用自定义标记的作用域,换成.InstancePerLifetimeScope()就和默认DI的Scoped完全一致了。

2. 模拟TryAddEnumerable的“避免重复注册”特性

Autofac没有直接和TryAddEnumerable完全对等的API,但如果你需要实现“只有当这个特定的MyCustomCircuit -> CircuitHandler注册不存在时才添加”的效果,可以加个注册检查:

// 先检查是否已经注册过MyCustomCircuit作为CircuitHandler
if (!builder.ComponentRegistry.IsRegistered(new TypedService(typeof(CircuitHandler), typeof(MyCustomCircuit))))
{
    builder.RegisterType<MyCustomCircuit>().As<CircuitHandler>().InstancePerLifetimeScope();
}

要是你的场景里不需要这么严格的重复校验,只是要把MyCustomCircuit注册为CircuitHandler并加入到服务集合中(和.NET DI的AddEnumerable行为一致),那你最初的写法调整生命周期后就完全够用——Autofac默认会把所有注册为CircuitHandler的实现自动纳入IEnumerable<CircuitHandler>的集合里,和默认DI的集合行为一致。

总结一下:

  • 仅需注册Scoped实现:用builder.RegisterType<MyCustomCircuit>().As<CircuitHandler>().InstancePerLifetimeScope();就可以
  • 需要完全等效TryAddEnumerable的“尝试添加”:加上注册检查逻辑即可

备注:内容来源于stack exchange,提问作者Raphael Theriault

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 14:02:42