如何在单例类中使用DbContext?

2024-02-29

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

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

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

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

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


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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在单例类中使用DbContext? 的相关文章

随机推荐