如何注入托管工作者服务?

How to inject into hosted worker service?

我有一个从默认的 .NET Core 模板创建的辅助服务。我有两个额外的服务想要 运行,一个发出一个事件,另一个使用它。所以理想情况下,它们都应该被注入到单个 Worker 托管服务中。我怎样才能做到这一点?我尝试了如下代码,但我得到了:System.InvalidOperationException: 'Unable to resolve service for type 'Receiver.IMessageReceiver' while attempting to activate 'MessageQueueReceiver.Worker'.'

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddSingleton<IMessageReceiver, MessageReceiver>();
                    services.AddSingleton<IWebhookMessageForwarder, WebhookMessageForwarder>();
                    services.AddHostedService<Worker>();
                });
    }
    public class Worker : BackgroundService
    {
        private readonly ILogger _logger;
        private readonly IMessageReceiver _messageReceiver;
        private readonly IWebhookMessageForwarder _forwarder;

        public Worker(ILogger<Worker> logger, 
            IMessageReceiver messageReceiver, 
            IWebhookMessageForwarder forwarder)
        {
            _logger = logger;
            _messageReceiver = messageReceiver;
            _forwarder = forwarder;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            _messageReceiver.MessageReceived += _forwarder.OnMessageReceived;
            _messageReceiver.RegisterHandlerAndReceiveMessages();

            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(TimeSpan.FromSeconds(60), stoppingToken);
            }
        }
    }

看起来问题出在初始化您的 class 之一。请检查的构造函数 Worker、Message Receiver 和 MessageForwarder class.

同时检查这一行,您正在创建接口的实例。

services.AddSingleton<IWebhookMessageForwarder, IWebhookMessageForwarder>()

我尝试了下面的代码并且成功了,它承载了一个 BackgroundService。

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
       Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
                services.AddSingleton<IMessageReceiver, MessageReceiver>();
                services.AddSingleton<IWebhookMessageForwarder, WebhookMessageForwarder>();
                services.AddHostedService<Worker>();
            });
}

public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;
    private readonly IMessageReceiver _messageReceiver;
    private readonly IWebhookMessageForwarder _forwarder;

    public Worker(IMessageReceiver messageReceiver,
        IWebhookMessageForwarder forwarder)
    {
        _messageReceiver = messageReceiver;
        _forwarder = forwarder;
    }

    public override Task StartAsync(CancellationToken cancellationToken)
    {
        return base.StartAsync(cancellationToken);
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            System.Console.WriteLine("Hello");
            await Task.Delay(TimeSpan.FromSeconds(60), stoppingToken);
        }
    }
}


public interface IWebhookMessageForwarder
{
}

public class WebhookMessageForwarder : IWebhookMessageForwarder
{
}

public interface IMessageReceiver
{
}

public class MessageReceiver : IMessageReceiver
{
}