首页 > 解决方案 > 如何在 IHostBuilder 扩展中访问 IServiceProvider?

问题描述

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

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

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

就像是:

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();
    });

标签: .netdependency-injectionnservicebus

解决方案


调用时还没有IServiceProvider可用UseNServiceBus的。UseNServiceBus在内部也只是使用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 需求可能会有所帮助。


推荐阅读