【问题标题】:How to create a singleton at the start of a grpc service?如何在 grpc 服务启动时创建单例?
【发布时间】:2020-08-17 02:10:00
【问题描述】:

我有一个应该在应用程序启动时创建的服务,我想向程序外部提供有关该服务的信息。

我的想法是一个 gRPC 服务器(.NET Core 3.1),它在程序开始时创建服务,并使用默认的 IoC 容器将服务转发到 gRPC 控制器。我的服务还应该能够使用默认 IServiceProvider 的其他服务(例如用于日志记录)。

我的第一种方法是在ConfigureServices 中创建服务并将实例传递给AddSingleton。这不起作用,因为我的服务需要 IServiceProvider 尚未在 ConfigureServices 中构建。

然后我发现你可以指定一个将服务提供者作为参数的工厂:

services.AddSingleton<IService>(serviceProvider => new Service(serviceProvider));

现在,我的服务可以访问所有其他服务,但只有在 gRPC 客户端请求有关服务的信息时才会创建它。

有没有办法立即实例化服务?

提前谢谢你。

【问题讨论】:

    标签: c# .net-core dependency-injection grpc


    【解决方案1】:

    您可以随时使用services.BuildServiceProvider()ConfigureServices 中创建ServiceProvider 的实例,并将其传递给您的Service 单例。但是请注意,在您创建ServiceProvider 之后 中注册的所有服务将无法通过提供程序访问。例如:

    public void ConfigureServices(IServiceCollection services)
    {
        var sp = services.BuildServiceProvider();
        var service = new Service(sp);
        services.AddSingleton(service);
    
        // ...
    
        services.AddScoped<IOtherService, OtherServiceImplementation>();
        var otherService = sp.GetService<IOtherService>();
        // otherService == null
    }
    

    所以...如果您不能等待创建单例直到请求访问它,您应该确保它仅在所有其他必要的服务都已注册之后创建。

    【讨论】:

    • 这个方法在我的情况下实际上是有效的,但会显示一个警告,你不应该在ConfigureServices 中调用BuildServiceProvider。因此,这种方法对我来说似乎有点棘手,可能不是最佳方法。无论如何,当没有人找到更好的解决方案时,我会接受你的回答。
    • @NicoSchreiner 并且该警告可能是我提到的原因 - 稍后注册的服务将不适用于服务提供商。如果您需要坚持立即实​​例化服务的要求,我认为您不会找到更简洁的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-28
    • 2021-04-27
    • 1970-01-01
    • 2017-08-11
    • 1970-01-01
    相关资源
    最近更新 更多