[英].NET Core Singleton Creation is called multiple times
我在.NET Core中將服務注冊為單例。 但是我看到單例的構造函數被多次調用。
services.AddSingleton<DbAuthorizationOptions, ContextAuthorizationOptions>();
我的上下文授權選項只是將實體類型字典發送給IValidators
,上下文授權選項被傳遞到DBContext
,以自動運行驗證。
在注冊服務期間,我還將動態驗證器與在DI中注冊的容器一起注冊。
var useDynamicValidator = serviceOption.ValidatorOptions != null;
if(useDynamicValidator)
{
//TODO: Extract this to before the register service no sense in building the provider each time
//TODO: Make this cleaner don't be dependent on Authorization options
var provider = services.BuildServiceProvider();
var authOptions = provider.GetService<DbAuthorizationOptions>();
var validator = BuildDynamicValidatorFactory(serviceOption).Invoke(provider, null);
authOptions.ValidatorOptions.AddValidatorForSet(validator);
}
我注意到,當我在提供程序上調用GetService
時,會收到一個新的單例,而不是現有的單例。 構建提供者是否會創建一個新的容器,以便重新注冊所有服務?
如果是這樣,我該如何調用一種方法來在現有IServiceProvider
的單例容器中注冊我的動態驗證器,是否可以在構建服務容器后立即調用一些注冊?
構建提供者是否會創建一個新容器,以便重新注冊所有服務?
是。 參見源代碼 。
如果是這樣,我該如何調用一種方法來向現有IServiceProvider在單例容器中注冊我的動態驗證器,是否可以在構建servicecontainer之后調用一次注冊?
我不是很了解為什么這是一個問題。 您應該在應用程序啟動時一次在Composition Root中注冊所有服務。
然后,DI容器負責解析應用程序的對象圖 。 應用程序本身不應該依賴它,也不需要更新它。
您應該在需要使用DbAuthorizationOptions
的地方注入它。
public class Foo : IFoo
{
private readonly DbAuthorizationOptions authOptions;
public Foo(DbAuthorizationOptions authOptions) // <-- Inject parameters
{
this.authOptions = authOptions ??
throw new ArgumentNullException(nameof(authOptions));
}
public void DoSomething()
{
// TODO: Inject the type that has the BuildDynamicValidatorFactory
// method and the serviceOption (whatever type that is) here
// either as a method parameter of this method, or a constructor
// parameter of this class.
var validator = BuildDynamicValidatorFactory(serviceOption).Invoke(provider, null);
// Now we have an instance of authOptions that can be used
authOptions.ValidatorOptions.AddValidatorForSet(validator);
}
}
請注意,如果將DI容器注入也通過DI解析的另一種類型(例如,控制器或過濾器),則DI容器會自動提供DbAuthorizationOptions
。
注意:從您的問題尚不清楚,您需要在哪里執行此操作。 您提到您希望它發生一次,這通常意味着將其放在應用程序啟動時。 但是用戶無法與啟動時運行的代碼進行交互。 因此,也許您可以使用filter 。 這一切都是在那里它發生在應用程序的生命周期取決於。
您可以聲明對IServiceProvider
的依賴關系-不要構建它,注入它。
public class SomeController
{
DbAuthorizationOptions authOptions;
public SomeController(IServiceProvider provider)
{
authOptions = provider.GetSerivce<DbAuthorizationOptions>();
}
}
但這是服務定位器的反模式。 在您提供了更多詳細信息之后,我對NightOwl888的帖子發表了評論時,工廠可能是一個更好的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.