【问题标题】:How to access IServiceProvider in IHostBuilder extensions?如何在 IHostBuilder 扩展中访问 IServiceProvider?
【发布时间】:2021-03-10 20:11:23
【问题描述】:

拥有net5.0 应用程序,我想利用NServiceBus.Extensions.Hosting 提供的UseNServiceBus(...) 扩展来构建端点,将其包装到IHostedService 并在应用程序启动/停止时运行/停止它。

不幸的是,我需要从容器访问其他类才能完全创建EndpointConfiguration。这是不可能的,因为没有容器 (IServiceCollection) 也没有提供者 (IServiceProvider)。

有什么诀窍,我可以解析传递给UseNServiceBus的lambda中的服务吗?

类似:

hostBuilder
    .ConfigureServices((hostContext, services) =>
    {
        services
            .AddSingleton<CoolEndpointConfigBuilder>()
            .AddSingleton<SomeDependency>(sp => 
            {
                /* 
                 * We can access sp in this context to resolve anything
                 * helpful in the process of SomeDependency's creation
                 */ 
            })
            .AddOtherDependencies()
        ;
    })
    .UseNServiceBus(hostContext => 
    {
        // How to get it here?
        IServiceProvider sp = PerformSomeVooDooToGetServiceProvider();

        var cecb = sp.GetRequiredService<CoolEndpointConfigBuilder>();

        /*
         * Which assembles EndpointConfiguration using the myriad of classes 
         * injected to the CoolEndpointConfigBuilder's constructor
         */
        return cecb.Build();
    });

【问题讨论】:

    标签: .net dependency-injection nservicebus


    【解决方案1】:

    当调用UseNServiceBus 时,还没有可用的IServiceProviderUseNServiceBus 在内部也只是使用 IHostBuilder.ConfigureServices 所以它受限于相同的约束。您正在尝试从容器中解析服务,而主机尚未创建 IServiceProvider。 NServiceBus 还需要主机管理的 DI 容器,因此在 NServiceBus 仍在配置时无法解决依赖关系。 本质上,您应该能够在不需要依赖注入的情况下配置端点。为什么您的配置需要 DI?

    如果您真的想解决这个问题(我强烈建议您不要这样做),您可以在配置时为您需要的类型创建一个临时 DI 容器,例如像

    hostBuilder
        .UseNServiceBus(hostContext => 
        {
            var tempServiceCollection = new ServiceCollection();
            tempServiceCollection.AddSingleton<CoolEndpointConfigBuilder>();
    
            var tempServiceProvider = tempServiceCollection.BuildServiceProvider();
    
            var cecb = tempServiceProvider.GetRequiredService<CoolEndpointConfigBuilder>();
    
            return cecb.Build();
        });
    

    这当然非常有限,但取决于您的 DI 需求可能会有所帮助。

    【讨论】:

    • 添加@sabacc 所说的内容:MS 明确指出您应该避免在他们的建议中使用BuildServiceProvider docs.microsoft.com/en-us/dotnet/core/extensions/…
    • 是的,就像这条评论一样。您不应该在 NServiceBus 的配置中使用IServiceProvider。他们唯一需要的就是IConfigurationIHostEnvironment。您的处理程序和 saga 与标准 dotnet 核心共享 DI。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多