你能重置.NET Core中的DI容器吗?

huangapple go评论62阅读模式
英文:

Can you reset the DI container in .NET Core?

问题

我们有多个网站在相同的ASP.NET Core代码库上运行。在appsettings.json中有一个SiteId,它定义了应该从数据库中加载哪个网站。然后我们设置了一个Singleton:

builder.Services.AddSingleton<Site>(provider =>
{
    short siteId = configuration.GetValue<short>("CoreSettings:SiteID");
    var db = provider.GetRequiredService<SomeDatabaseService>();
    return db.GetSite(siteId);
}

Site对象是非常静态的。它包含基本数据,如CompanyName和Phone,很少更改。但是,这些数据偶尔会发生更改,我们希望Site单例能够更新。

我知道我们可以将Site更改为scoped,但是当Site在数月内都没有更改时,这似乎会带来很多DI开销。而且,我们将不得不将许多其他明显是单例的服务更改为scoped,因为它们依赖于Site。

是否有一种方法可以告诉DI容器进行重置?我基本上想说:“嘿,DI,把一切都丢掉,然后重新构建”。

目前,我们不得不在IIS中重置应用程序池才能看到Site的任何更改。

英文:

We have several websites running on the same ASP.NET Core codebase. There's a SiteId in the appsettings.json that defines which website should be loaded from the database. We then have a Singleton set up:

builder.Services.AddSingleton&lt;Site&gt;(provider =&gt;
{
    short siteId = configuration.GetValue&lt;short&gt;(&quot;CoreSettings:SiteID&quot;);
    var db = provider.GetRequiredService&lt;SomeDatabaseService&gt;();
    return db.GetSite(siteId);
}

The Site object is very static. It has basic data like CompanyName and Phone that rarely changes. However, this data can occasionally change and we'd like the Site singleton to get updated.

I know that we could change the Site to scoped, but this seems like a lot of DI overhead when the Site can go months without changing. Plus we'd have to change a lot of other services that are obviously singletons to scoped, because they depend on the Site.

Is there a way to tell the DI container to reset? I basically want to say "Hey DI, throw everything away and rebuild".

Right now, we're having to reset the application pool in IIS to see any changes to the Site.

答案1

得分: 2

Is there a way to tell the DI container to reset? I basically want to say "Hey DI, throw everything away and rebuild".
没有。至少不在默认的 DI 容器中。

TBH 倒更像是缓存问题,而不是 DI 问题。我会考虑重新制定获取 Site 的方法,引入内存缓存,设置一些过期时间和/或管理端点以获取新值。

but this seems like a lot of DI overhead
但这似乎有很多 DI 开销。

我会说切换到 Scoped 以及相应的 DI 开销本身非常小,唯一值得考虑的开销是不必要的数据库查询,但这可以通过缓存来减轻。

P.S.

如果 Site 不是存储在数据库中而是存储在配置文件中,另一个值得注意的方法是使用 Options 模式与 IOptionsMonitor

英文:

> Is there a way to tell the DI container to reset? I basically want to say "Hey DI, throw everything away and rebuild".

No. At least not in the default DI container.

TBH sounds much more like caching problem then DI one. I would consider reworking approach for getting the Site by introducing in-memory cache with some expirations set up and/or management endpoint to fetch new values.

> but this seems like a lot of DI overhead

I would say that switching to Scoped and corresponding DI overhead itself is very minimal, the only overhead worth considering is the unnecessary querying the database - but this should be mitigated via cache.

P.S.

If Site was not stored in the database but in configuration file another notable approach would be using Options pattern with IOptionsMonitor.

huangapple
  • 本文由 发表于 2023年2月18日 03:18:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75488455.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定