gpt4 book ai didi

c# - 如何在单例类中使用 DbContext?

转载 作者:行者123 更新时间:2023-12-02 01:33:37 25 4
gpt4 key购买 nike

我实现了一个类 EUMemberChecker,它负责检查一个国家是否是欧盟成员。为了完成它的工作,该类包含一个方法 public bool IsEUMember(string country)。用于检查一个国家是否是欧盟成员的数据存储在 PostgreSQL 数据库表中。

我想通过 AddSingleton 将其添加为单例服务,从而使此类通过 DI 可用。这样做的原因是它应该只在应用程序启动时从数据库中加载一次欧盟成员。如果我通过 AddScoped 添加此类,它的每个实例都需要从数据库中加载自己的欧盟成员列表,在我看来,这将是一个很大的开销。

我的问题是我无法将此类添加为单例,因为它使用我的 DbContext,它是作为作用域服务添加的。无论如何这样做,都会导致运行时错误 Dependency ...DatabaseContext {ReturnDefault} 作为参数“context” reuse CurrentScopeReuse {Lifespan=100} lifetime shorter than its parent's: singleton ... {ReturnDefault} as parameter .. ..

因此,我似乎必须将我的类添加为作用域服务,从而导致额外的数据库调用来为该类的每个实例加载欧盟成员国。

我是否在此处错误地应用了单一职责原则,或者我该如何解决这个问题?如何确保欧盟成员不会无缘无故地从数据库中多次加载?

最佳答案

有几种解决方案可以解决这个问题。以下是我能想到的选项:

  • EUMemberChecker 设为作用域,但将缓存部分从类中拉出,并将其作为单例服务注入(inject)。
  • 使 EUMemberChecker 成为您的 Composition Root 的一部分允许将 Container 实例(例如 IServiceProvider)注入(inject)该类。这允许创建一个范围实例,您可以从中解析,例如 DbContext。如果该类包含业务逻辑,最好从该类中提取它并将其也注入(inject)到该类中;您希望 Composition Root 中的代码量尽可能少。
  • 忽略并取消警告,因为您似乎确信这不会在您的特定情况下造成任何问题。请注意,对于 MS.DI,可能没有一种简单的方法来抑制此错误。
  • 在创建缓存时在 EUMemberChecker 中手动构造 DbContext。这可能意味着您需要将配置值注入(inject) EUMemberChecker,例如连接字符串,这显然是 DbContext 所需要的。
  • 在进行容器注册之前从数据库加载数据,并在注册时手动提供此缓存。例如:services.AddSingleton(c => new EUMemberChecker(loadedMembers))
  • 通过调用某种Initialize 方法在启动时直接初始化EUMemberChecker。加载的成员可以提供给方法,或者您可以传入 DbContext 以便 Initialize 可以在内部进行查询。此 DbContext 可以在启动时从容器中解析,可能是通过从手动创建的范围中解析它。

哪个选项最好,取决于很多实现细节,因此您必须决定哪个最适合您的需求。

关于c# - 如何在单例类中使用 DbContext?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72872402/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com