在单例服务中解析依赖项
目录
在依赖注入系统中,依赖项的生命周期通常分为瞬时的(Transient)、作用域的(Scoped)、单例的(Singleton)三种。单例生命周期的服务通常会在首次调用时创建,后续每此调用都会使用同一实例。
单例服务若依赖其他生命周期为瞬时或作用域的服务时,无法通过构造函数注入依赖项。构造函数只会在创建实例时调用一次,若将依赖项通过构造函数注入并赋值给单例服务的本地成员,依赖项的生命周期结束后销毁后,指向依赖项的本地成员将会指向空引用,且永远不会再次被赋值(只在调用构造函数时赋值)。运行时会抛出异常Cannot consume scoped service 'XXX' from singleton 'XXX'.
。
解决方案
在依赖瞬时生命周期或作用域生命周期依赖项的单例服务中,不直接通过构造函数注入依赖项,而是注入IServiceScopeFactory
,在需要用到依赖项的方法中,通过IServiceScopeFactory
创建作用域并解析依赖项。
public class MySingletonService : IMySingletonService
{
private readonly IServiceScopeFactory _scopeFactory;
public MySingletonService(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public void Scoped()
{
using var scope = _scopeFactory.CreateScope();
var ctx = scope.ServiceProvider.GetRequiredService<MyDbContext>();
}
}
关注微信公众号“捕获异常”,获取最新文章推送,提升你的技能。