c# - .NET Core Singleton Creation 被多次调用

标签 c# asp.net-core dependency-injection .net-core

我正在 .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 注册我的动态验证器,有没有办法在构建服务容器后调用一些注册?

最佳答案

Does building the provider create a new container so all of the services get reregistered?

是的。参见 the source code .

If so, How can I call a method to register my dynamic validators in the singleton container with the existing IServiceProvider, is there a way to invoke some registration once after the servicecontainer is built?

我不太明白为什么这是个问题。您应该在应用程序启动时在 Composition Root一次注册您的所有服务.

然后 DI 容器负责解析应用程序的对象图。应用程序本身不应该依赖它,也不需要更新它。

您应该在需要使用它的地方注入(inject) 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 容器自动提供 DbAuthorizationOptions 如果注入(inject)到另一种也通过 DI 解析的类型(例如 Controller 或过滤器)。

NOTE: It isn't very clear from your question where you need to do this. You mention that you want it to happen once, which usually means to put it at application startup. But users cannot interact with code that runs at startup. So, maybe you could use a filter. It really all depends on where in the lifecycle of the application it has to happen.

关于c# - .NET Core Singleton Creation 被多次调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48856483/

相关文章:

c# - 如何使用 Java 在 Windows 上创建虚拟磁盘(letter、share 等)?

c# - 路由添加静态段让分页更友好asp.net core

c# - .net Core 2.0 web api 400错误使用Validateantiforgerytoken

php - 使用 Symfony2 3.0+ 将 EntityManager 注入(inject)嵌入式 FormTypes

c# - 使用 SSH.NET 连接到远程主机

c# - 在 n 秒不活动后关闭 WPF 应用程序

c# - 什么是DenseVector?如何使用?

asp.net-core - Cookie 身份验证过期不会重新路由到登录页面

c# - ASP.NET Core Singleton 实例与 Transient 实例性能

C# .Net Core 依赖注入(inject),向构造函数注入(inject)多个参数