.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
相关产品推荐
相关产品推荐

