【问题标题】:ASP.NET Core Generic Host (HostBuilder) Unable to resolve service for type ... while attempting to activateASP.NET Core Generic Host (HostBuilder) Unable to resolve service for type ... 尝试激活时
【发布时间】:2018-10-12 20:32:26
【问题描述】:

我的意图只是使用通用主机在控制台应用程序中从另一个微服务调用一个微服务。

它在运行时失败并出现以下异常。我已经阅读了数十篇与 WebHostBuilder 相关的帖子,但无法将这些讨论与我试图用 HostBuilder 做的事情联系起来。我显然缺少一些基本的东西,并且非常感谢指导。下面是一个人为的代码示例。附言我相信我已经完成了适当的格式化和标记工作,以安抚那些真正知道自己在做什么的人 - 显然我不知道!

例外

System.InvalidOperationException: '在尝试激活 'MyNoobProject.DoSomethingWithToDo' 时,无法解析类型 'MyNoobProject.IToDo' 的服务。'

程序.cs

using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

public static async Task Main(string[] args)
    {
        var builder = new HostBuilder()
            .ConfigureServices((hostContext, services) =>
            {
                services.AddSingleton<IHostedService, ToDo>();
                services.AddSingleton<IHostedService, DoSomethingWithToDo>();

            })                
            .ConfigureLogging((hostingContext, logging) => {
               logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                logging.AddConsole();
            });;

        await builder.RunConsoleAsync();
    }

StackOverflow.cs

using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

namespace MyNoobProject
{
interface IToDo
{
    Task Add(int i);
    void Dispose();
}

class ToDo : IHostedService, IDisposable, IToDo
{
    private BlockingCollection<int> _blockingCollection;

    private readonly ILogger _logger;

    public ToDo(ILogger<ToDo>logger)
    {
        _logger = logger;
    }

    public Task Add(int i)
    {
        _blockingCollection.Add(i);
        return Task.CompletedTask;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _blockingCollection = new BlockingCollection<int>();
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _blockingCollection.CompleteAdding();
        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _blockingCollection.Dispose();
    }
}

interface IDoSomethingWithToDo
{

}

class DoSomethingWithToDo : IHostedService, IDisposable, IDoSomethingWithToDo
{
    private IToDo _todo;

    public DoSomethingWithToDo(IToDo todo)
    {
        _todo = todo;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _todo.Add(1);
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }

    public void Dispose()
    {

    }
}
}

【问题讨论】:

  • 您需要注册IToDo
  • @Daniel A. White 您能否在我的代码示例的上下文中为我拼写出来?谢谢。
  • ILogger 更改为ILogger&lt;ToDo&gt;
  • @Kirk Larkin 问题已正式编辑。

标签: c# dependency-injection .net-core-2.1


【解决方案1】:

服务提供者无法解析IToDo 接口,因为它没有向服务集合注册。

所以您已经将ToDo 实现注册为单例托管服务。

services.AddSingleton<IHostedService, ToDo>();
services.AddSingleton<IHostedService, DoSomethingWithToDo>();

如果您想在其他服务的构造函数中使用接口,我建议对其进行一些重组。

由于服务有一个简单的构造函数,您可以在组合根中对其进行初始化并应用必要的注册

var todo = new ToDo();
services.AddSingleton<IToDo>(todo);
services.AddSingleton<ToDo>(todo);
services.AddSingleton<IHostedService>(todo);
services.AddSingleton<IHostedService, DoSomethingWithToDo>();

这样注入DoSomethingWithToDo的构造函数的接口将使用启动时定义的单例

如果ToDo 也有依赖通过构造函数注入,它可以遵循类似的模式,但现在我们需要使用委托工厂来延迟初始化,以便可以解析和注入依赖。

//adding implementation first
services.AddSingleton<ToDo>();
//adding options for interfaces
services.AddSingleton<IToDo>(_ => _.GetService<ToDo>());
services.AddSingleton<IHostedService>(_ => _.GetService<ToDo>());
//...
services.AddSingleton<IHostedService, DoSomethingWithToDo>();

【讨论】:

  • 在我提供的初始示例中效果很好。非常感激。但是我感觉有点傻,因为我的真实世界项目构造函数并不简单,我又被困住了。我没有提前问正确的问题。对不起。已编辑问题以反映以 ILogger 作为参数的构造函数。
  • @TimDude 根据新信息检查更新。目前的情况是我们要求minimal reproducible example(强调完整)的原因,以便那些试图帮助的人全面了解实际问题。
  • 适当地注意到并谢谢你。为了其他任何人的答案的完整性 - 在实施答案时,我遇到了一个不相关的错误无法解析类型“Microsoft.Extensions.Logging.ILogger”的服务,同时尝试激活...我在这里找到了解释github.com/aspnet/Logging/issues/700
猜你喜欢
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-23
  • 2023-03-24
  • 2014-02-08
  • 2017-09-30
  • 2019-05-30
相关资源
最近更新 更多