我实现了一个类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(使用前将#替换为@)