C# ASP.NET核心通用主机(HostBuilder)无法解析类型的服务。。。试图激活时

C# ASP.NET核心通用主机(HostBuilder)无法解析类型的服务。。。试图激活时,c#,dependency-injection,.net-core-2.1,C#,Dependency Injection,.net Core 2.1,我的意图只是使用通用主机从控制台应用程序中的另一个调用一个微服务 它在运行时失败,出现以下异常。我已经阅读了几十篇关于WebHostBuilder的帖子,但无法将这些讨论与我试图用HostBuilder做的事情联系起来。很明显,我遗漏了一些基本的东西,我真的很感激你的指导。下面是一个精心设计的代码示例。另外,我相信我在格式化和标记方面做了适当的工作,以安抚那些真正知道自己在做什么的人——显然我不知道 例外情况 System.InvalidOperationException:“在尝试激活“MyN

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

它在运行时失败,出现以下异常。我已经阅读了几十篇关于WebHostBuilder的帖子,但无法将这些讨论与我试图用HostBuilder做的事情联系起来。很明显,我遗漏了一些基本的东西,我真的很感激你的指导。下面是一个精心设计的代码示例。另外,我相信我在格式化和标记方面做了适当的工作,以安抚那些真正知道自己在做什么的人——显然我不知道

例外情况

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

Program.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();
    }
使用System.Threading.Tasks;
使用Microsoft.Extensions.Hosting;
使用Microsoft.Extensions.Configuration;
使用Microsoft.Extensions.DependencyInjection;
使用Microsoft.Extensions.Logging;
公共静态异步任务主(字符串[]args)
{
var builder=新主机生成器()
.ConfigureServices((主机上下文,服务)=>
{
services.AddSingleton();
services.AddSingleton();
})                
.ConfigureLogging((hostingContext,logging)=>{
logging.AddConfiguration(hostingContext.Configuration.GetSection(“logging”));
logging.AddConsole();
});;
等待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()
    {

    }
}
}
使用Microsoft.Extensions.Hosting;
使用制度;
使用System.Collections.Concurrent;
使用系统线程;
使用System.Threading.Tasks;
名称空间MyNoobProject
{
接口IToDo
{
任务添加(int i);
无效处置();
}
类ToDo:IHostedService、IDisposable、IToDo
{
私人封锁收集_封锁收集;
专用只读ILogger\u记录器;
公共待办事项(iLogger)
{
_记录器=记录器;
}
公共任务添加(int i)
{
_阻止收集。添加(i);
返回Task.CompletedTask;
}
公共任务StartSync(CancellationToken CancellationToken)
{
_blockingCollection=新建blockingCollection();
返回Task.CompletedTask;
}
公共任务StopAsync(CancellationToken CancellationToken)
{
_blockingCollection.CompleteAdding();
返回Task.CompletedTask;
}
公共空间处置()
{
_blockingCollection.Dispose();
}
}
接口IDoSomethingWithToDo
{
}
类DoSomethingWithToDo:iHostService、IDisposable、IDoSomethingWithToDo
{
私人IToDo_todo;
公共DoSomethingWithToDo(IToDo todo)
{
_todo=todo;
}
公共任务StartSync(CancellationToken CancellationToken)
{
_待办事项.加入(1);
返回Task.CompletedTask;
}
公共任务StopAsync(CancellationToken CancellationToken)
{
返回Task.CompletedTask;
}
公共空间处置()
{
}
}
}

服务提供商无法解析
IToDo
接口,因为它未在服务集合中注册

因此,您已经将
ToDo
实现注册为单例托管服务

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

您需要注册
IToDo
@Daniel A。怀特,请您在我的代码示例中为我详细说明一下?谢谢。将
ILogger
更改为
ILogger
@Kirk-Larkin问题经过适当编辑。在我提供的初始示例中效果非常好。非常感谢。然而,我觉得有点傻,因为我的真实世界的项目构造函数并不简单,我又被卡住了。我没有事先问对问题。很抱歉问题已被编辑,以反映以ILogger为参数的构造函数。@TimDude检查基于新信息的更新。这种现状就是我们要求(强调完整性)的原因因此,那些试图提供帮助的人对实际问题有一个完整的了解。请注意并感谢您。对于其他人的答案的完整性-在实现该答案时,我在尝试激活时遇到了一个不相关的错误,无法解析“Microsoft.Extensions.Logging.ILogger”类型的服务。。。我在这里找到了一个解释
var todo = new ToDo();
services.AddSingleton<IToDo>(todo);
services.AddSingleton<ToDo>(todo);
services.AddSingleton<IHostedService>(todo);
services.AddSingleton<IHostedService, DoSomethingWithToDo>();
//adding implementation first
services.AddSingleton<ToDo>();
//adding options for interfaces
services.AddSingleton<IToDo>(_ => _.GetService<ToDo>());
services.AddSingleton<IHostedService>(_ => _.GetService<ToDo>());
//...
services.AddSingleton<IHostedService, DoSomethingWithToDo>();