5

我有一些类库为我创建的应用程序提供服务,并且由于遗留原因,它们与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方法可以更改为返回一个IServiceProvider,这DryIoc可以为我提供。

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

重要的代码是这样的:

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

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

  • ConfigureServices(Action<HostBuilderContext, IServiceCollection> configureDelegate)
  • ConfigureServices(this IHostBuilder hostBuilder, Action<IServiceCollection> configureDelegate)

在这方面,似乎没有任何条款可以返回或使用 aIServiceProvider或任何其他DryIoc可以为我提供的东西。

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

4

1 回答 1

5

@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类是在配置过程中解析的,可以使用构造函数来配置容器。可以使用什么都不做的虚拟类。

于 2018-08-16T12:34:53.603 回答