将Unity DI与基于HostBuilder的.NET Core控制台应用程序一起使用

时间:2019-12-03 18:12:09

标签: dependency-injection .net-core unity-container

使用ASP.NET MVC Core,可以通过加载适当的NuGet软件包(Unity.Container和Unity.Microsoft.DependencyInjection)并在构建Web时调用UseUnityServiceProvider()扩展方法来使用Unity DI软件包。托管在Program.cs中。此扩展方法基于IWebHostBuilder接口。初始化主机后,可以通过.NET Core GetService接口和任何构造函数注入来访问Unity DI功能。

我正在基于控制台的应用程序上工作,该应用程序将使用HostBuilderIHostBuilder界面。我已尝试通过UseUnityServiceProvider()扩展名(可在此处使用:https://github.com/unitycontainer/microsoft-dependency-injection/blob/master/src/HostingExtension.cs)来重新实现注册逻辑,这是针对ConfigureServices()的{​​{1}}方法调用的一部分,但是服务提供者的变化似乎对下游DI调用不可见。

在使用IHostBuilder创建的应用程序中,有没有人成功让Unity可以使用Microsoft DI方法?

更新 根据要求,以下是我尝试的示例(摘自Unity来源)。当然,这是行不通的。 HostBuilder具有一个构造函数,该构造函数应注入TestService中定义的对象。这不会发生。

MyUnityExtension

1 个答案:

答案 0 :(得分:0)

不确定要使用new UnityContainer().AddNewExtension<MyUnityExtension>()实现什么。

如果只希望将某些注册服务注入TestService,为什么不只使用IUnityContainer.RegisterType<TInterface, TImplementation>()

这是Program.cs(.NET Core 3.1,Microsoft.Extensions.Hosting v3.10,Unity.Microsoft.DependencyInjection v5.11.5)中有效的IHost设置:

public static async Task Main(string[] args)
{
    var container = new UnityContainer();
    container.RegisterType<IService, MyService>();

    var builder = new HostBuilder()
      .ConfigureServices((hostContext, services) =>
      {
          services.AddHostedService<TestService>();
      })
      .ConfigureLogging((hostingContext, logging) =>
      {
          logging.AddConsole();
      })
      .UseUnityServiceProvider(container);
    await builder.RunConsoleAsync();
}

界面:

public interface IService
{
    string Name { get; }
}

实现:

public class MyService : IService
{
    public string Name => "My name";
}

TestService:

public class TestService : IHostedService
{
    private readonly IService service;
    private readonly ILogger logger;

    public TestService(IService service, ILogger<TestService> logger)
    {
        this.service = service;
        this.logger = logger;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        this.logger.LogInformation("Hello {n}", this.service.Name);
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}