简单的回答是不可以的,为什么呢?不管是自带的DI还是使用autofac,都不可以实现的。这个根源在于ASP.Net Core的设计,不在于Ioc框架,在ASP.Net中我们所有的服务提供容器(ServiceProvder)在程序启动后就已经指定在上下文中componentContext。这个就是我们说的范围scope。一但这个Scope指定后不管在哪里都是无法替换的,也就是说无法再修改了。即使如你所愿你拿到RootContainer,重新添加修改注册类型,但是旧的scope一直存在,也不会受影响。

在原生的框架里我们是通过ServiceCollections 来添加注册类型的。一但启动它会调用方法 services.BuildServiceProvder(),然后返回一个容器(IServiceProvder)来添加到上下文中。除了重启程序外我们无法改变它。

为什么设计成不可变与替代思路

ASP.NET Core 的服务容器在宿主启动完成那一刻就固化了:BuildServiceProvider 之后的注册表不再接受修改,所有已解析的服务都引用同一个容器快照。这是刻意设计——保证容器线程安全、解析行为可预期,也避免了运行中"同一接口一半新一半旧实现"的混乱状态。Autofac 老版本曾提供 Update 方法,新版本已移除,也是同样的考量。

  • 把"运行期换实现"改为"注册时注册工厂":注入 Func 或工厂类,在解析时再决定返回哪个实现;
  • 配置类需求用 IOptionsMonitor,可在不重启的情况下感知配置变更;
  • 确实需要整批更换实现时,把修改做进代码后滚动重启(容器编排下很方便);
  • 插件式动态加载建议独立 AppDomain/AssemblyLoadContext + 独立容器,而不是改主容器。