【问题标题】:Use HostBuilder.ConfigureServices with DryIoc container?将 HostBuilder.ConfigureServices 与 DryIoc 容器一起使用?
【发布时间】:2018-08-16 08:14:05
【问题描述】:

我有一些类库为我创建的应用程序提供服务,并且由于遗留原因,它们与DryIoc 紧密绑定。也就是说,服务注册是紧密绑定的,而不是实际的服务。

如果可以的话,我宁愿不要只是在不必要的情况下更改该代码。

创建一个新的 ASP.NET MVC Core 应用程序我能够通过更改 ConfigureServices 方法来使用 DryIoc 以返回一个 IServiceProvider,如下所示:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddMvc().AddControllersAsServices();

    var container = new Container().WithDependencyInjectionAdapter(services);
    return container.ConfigureServiceProvider<CompositionRoot>();
}

(这是凭记忆,所以可能不是 100% 正确,但这并不重要)

重要的变化是void 方法可以更改为返回IServiceProviderDryIoc 可以提供给我。

但是,对于我想用于控制台应用程序、后台服务等的HostBuilder,配置服务的方法不接受IServiceProvider,所以我不知道该怎么做。

重要的代码是这样的:

var builder = new HostBuilder()
    .ConfigureAppConfiguration((hostingContext, config) => { ... })
    .ConfigureServices((hostContext, services) =>
    {
        services.AddOptions();
        // configure services
    })
    .ConfigureLogging((hostingContext, logging) => { ... });

上面的ConfigureServices 方法有一个重载和一个扩展方法:

  • ConfigureServices(Action&lt;HostBuilderContext, IServiceCollection&gt; configureDelegate)
  • ConfigureServices(this IHostBuilder hostBuilder, Action&lt;IServiceCollection&gt; configureDelegate)

似乎没有任何规定可以返回或使用IServiceProviderDryIoc 在这方面可以为我提供的任何其他东西。

这可能吗?有没有办法弥合差距?还是我只需要切换到使用 Microsoft IServiceCollection 来为我的类库?由于它们已在许多项目中使用,我宁愿不要仅仅因为在这种特定情况下看起来最简单而进行更改,但如果必须,我必须这样做。

【问题讨论】:

    标签: c# .net-core dryioc microsoft.extensions.hosting


    【解决方案1】:

    @Nkosi 提供了一个不正确的答案(但在 ASP.NET 应用程序的上下文中是正确的),评论线程引发了关于方法 UseServiceProviderFactory 的讨论,结果证明这是解决方案,所以谢谢大家。

    要使用UseServiceProviderFactory,我必须自己实现一个类,并将适当的 nuget 包引用添加到我的项目中。

    步骤如下:

    1. 添加对DryIoc.dll 的引用(不出所料)
    2. 添加对DryIoc.Microsoft.DependencyInjection的引用
    3. 更改注册码
    4. 提供UseServiceProviderFactory所需框架的自定义实现

    原始代码如下所示:

    var builder = new HostBuilder()
        .ConfigureAppConfiguration((hostingContext, config) => { ... })
        .ConfigureServices((hostContext, services) =>
        {
            services.AddOptions();
            // configure services
        })
        .ConfigureLogging((hostingContext, logging) => { ... });
    

    以下是改用的:

    var builder = new HostBuilder()
        .ConfigureAppConfiguration((hostingContext, config) => { ... })
        .ConfigureServices((hostContext, services) =>
        {
            services.AddOptions();
            // configure services
        })
    
        //////////////////// ADD THIS vvvvvvvv
        .UseServiceProviderFactory(new DryIocServiceProviderFactory())
        .ConfigureContainer<Container>((hostContext, container) =>
        {
            container.Register<...>();
        })
        //////////////////// ADD THIS ^^^^^^^^
    
    
        .ConfigureLogging((hostingContext, logging) => { ... });
    

    然后提供DryIocServiceProviderFactory的这个实现:

    internal class DryIocServiceProviderFactory : IServiceProviderFactory<IContainer>
    {
        public IContainer CreateBuilder(IServiceCollection services)
            => new Container().WithDependencyInjectionAdapter(services);
    
        public IServiceProvider CreateServiceProvider(IContainer containerBuilder)
            => containerBuilder.ConfigureServiceProvider<CompositionRoot>();
    }
    

    上面的CompositionRoot类是在配置时解析的,可以使用构造函数来配置容器。可以使用什么都不做的虚拟类。

    【讨论】:

    • 请注意,如果您实际上没有在那里注册任何服务,则有关ConfigureServices 的部分是可选的,但是至少对我而言,Microsoft 依赖注入注册的某些部分仍然有点黑魔法所以有些部分还是要依赖通过IServiceCollection注册服务,比如配置。
    • 另外请注意,我的示例中对各种配置方法的调用只是您可以配置和调用的部分内容,如果您想配置托管环境,这些内容仍然是必需的, 提供 appsettings.json 等。
    • 它可以更多地缩短为扩展方法UseDryIoc() 或几种方法,包括具有组合根的方法。新的nuget包可能是?
    • 就我个人而言,我一直远离 compositionroot 方式,因为我在注入完整容器以进行注册和注册服务时遇到了麻烦,它似乎与 IRegistrator 一起工作得更好,但缺少一些方法在IRegistrator 上出现在IContainer/Container 上,所以现在我还没有使用它。
    • 具体来说,UseInstance 不适用于IRegistrator,而且我还没有弄清楚如何哄.Register 注册现有实例,也许这同样容易?我是否打算使用 .RegisterDelegate 来添加一个将被调用以返回现有实例的 shim 委托?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-13
    • 2014-03-10
    • 2021-08-18
    • 2011-06-05
    相关资源
    最近更新 更多