我不能在系统上的单例中使用作用域服务,但在azure上,它在发布后可以工作。
在我的Net5服务中,我需要从azure ServiceBus侦听器向SQL-DB中写入。请这样做,我使用"服务"。AddDbContext"用于DB和"服务。AddSingleton'用于ServiceBus侦听器。侦听器服务获取构造函数中的dbContext。由于我总是将服务部署到azure来测试它,所以直到我尝试在本地机器上启动(调试(完全相同的服务时,我才收到这个错误。
Azure有什么不同?我需要听众立即开始。如果它被限定了范围,它就不会启动。
在开发人员模式下运行时,ASP。NET核心配置系统(MS.DI(防止在Singleton使用者中(直接或间接(注入作用域依赖项。它通过其范围验证功能来实现这一点。这样做是因为注入Scoped依赖项通常具有状态,并且Singleton将保持此类Scoped依存项的活动状态。这是一个名为Captive Dependencies的常见陷阱。
MS。然而,DI仅在调试模式下执行此检查;可能是因为这项检查需要时间。这意味着在部署应用程序后,MS.DI将不会检查这种陷阱,因为在这种情况下,应用程序不再以开发模式运行。
但即使没有例外,你也会认为"它在出版后工作";,您应该防止将短期依赖项(如Scoped依赖项(注入到长期依赖项(Singleton(中,因为这可能会导致大量难以找到的错误,尤其是DbContext实例,因为它们不是线程安全的,而且它们的数据很快就会过时。
这意味着,在任何可能的情况下,都要将使用者(听众(的生存期降低到Scoped或Transient。然而,如果应用程序只有该侦听器的一个实例,那么降低生活方式不会有任何影响;实例本身就是Singleton,不管它的生活方式如何。在这种情况下,监听器应该成为CompositionRoot的一部分,这样它就可以直接管理IServiceScope
。通过这种方式,您可以在每次调用侦听器时从新的IServiceScope解析DbContext
实例。