Chr*_*ris 4 c# singleton dependency-injection single-responsibility-principle asp.net-core
我实现了一个类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
,但将缓存部分从类中拉出,并将其作为单例服务注入。EUMemberChecker
的一部分,以允许将容器实例(例如)注入到该类中。这允许创建一个范围实例,您可以从中解析,例如. 如果类包含业务逻辑,最好从类中提取业务逻辑并将其注入到类中;您希望组合根中的代码量尽可能小。IServiceProvider
DbContext
DbContext
手动构建。EUMemberChecker
这可能意味着您需要将配置值注入到 中EUMemberChecker
,例如连接字符串,这DbContext
显然是需要的。services.AddSingleton(c => new EUMemberChecker(loadedMembers))
.EUMemberChecker
通过调用某种方法在启动时直接初始化Initialize
。可以将加载的成员提供给该方法,或者您可以传入DbContext
以便Initialize
可以在内部进行查询。这DbContext
可以在启动时从容器中解决,可能是通过手动创建的范围来解决。哪一个选项最好,取决于许多实施细节,因此您必须决定哪一个最适合您的需求。
归档时间: |
|
查看次数: |
1377 次 |
最近记录: |