Autofac.Extensions.DependencyInjection v8.0.0.0中IServiceScopeFactory变更适配咨询
我有一个基于Autofac + Autofac.Extensions.DependencyInjection的应用,升级到v8.0.0.0前运行正常。根据发布说明,v8的变更导致显式创建的作用域不再具备层级关系,而我的应用里多处通过显式创建作用域实现工作单元。
具体问题:部分服务通过InstancePerMatchingLifetimeScope注册为每个命名作用域单实例。当从命名作用域显式创建的新作用域中激活服务时,解析该命名作用域对应的服务会失败,这完全不符合命名作用域的设计预期。
我清楚命名作用域是Autofac原生特性,原本应该避免使用IServiceProvider,转而用Autofac原生构造创建工作单元,但应用里有几个无法控制的组件必须要求显式的IServiceProvider实例,所以一直采用微软的DI API。
请问在保留使用MS IServiceScope/IServiceProvider接口的前提下,有没有办法解决这个升级带来的问题?还是必须完全改用Autofac原生API?
解决方案
1. 自定义IServiceScopeFactory适配命名作用域层级
通过自定义IServiceScopeFactory,让MS API创建的作用域关联到Autofac的命名作用域上下文,而非创建独立根作用域,以此保留层级关系。
示例实现:
public class AutofacNamedScopeServiceScopeFactory : IServiceScopeFactory { private readonly ILifetimeScope _rootScope; private readonly string _namedScopeTag; public AutofacNamedScopeServiceScopeFactory(ILifetimeScope rootScope, string namedScopeTag) { _rootScope = rootScope; _namedScopeTag = namedScopeTag; } public IServiceScope CreateScope() { // 从目标命名作用域创建子作用域,继承上下文 var childNamedScope = _rootScope.BeginLifetimeScope(_namedScopeTag); return new AutofacServiceScope(childNamedScope); } }
注册该工厂到Autofac容器,绑定对应命名作用域标签:
builder.RegisterType<AutofacNamedScopeServiceScopeFactory>() .As<IServiceScopeFactory>() .WithParameter("namedScopeTag", "YourNamedScopeTag") .InstancePerMatchingLifetimeScope("YourNamedScopeTag");
后续在命名作用域内获取IServiceScopeFactory创建的新作用域,就能正常解析InstancePerMatchingLifetimeScope注册的服务。
2. 局部转换IServiceProvider为Autofac原生作用域
利用Autofac对IServiceProvider的扩展,将MS的服务提供器转换为ILifetimeScope,再创建带命名的子作用域,最后包装回MS的IServiceScope供第三方组件使用。
示例代码:
// 假设已获取第三方组件要求的IServiceProvider实例 var msServiceProvider = ...; // 转换为Autofac原生生命周期作用域 var autofacScope = msServiceProvider.GetAutofacRoot(); // 创建继承当前上下文的命名子作用域 var childNamedScope = autofacScope.BeginLifetimeScope("YourNamedScopeTag"); // 包装为MS IServiceScope返回 var msServiceScope = new AutofacServiceScope(childNamedScope);
这种方式无需全局修改,适合局部适配第三方组件的场景。
3. 临时调整服务注册(过渡方案)
如果上述适配方式无法落地,可临时将部分InstancePerMatchingLifetimeScope注册改为InstancePerLifetimeScope,结合MS IServiceScope的上下文控制实例生命周期。但此方案会丢失命名作用域的精确隔离能力,仅作为短期过渡使用。
若以上方案均无法满足需求,可能需要逐步替换依赖MS DI API的第三方组件,或完全切换到Autofac原生API管理命名作用域——毕竟v8的变更旨在对齐MS DI的作用域模型,Autofac原生API才是命名作用域的最优实践。
内容的提问来源于stack exchange,提问作者James Hobson

