[英].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.