voxtm
voxtm

Reputation: 490

How to inject into hosted worker service?

I have a worker service created from the default .NET Core Template. I have two additional services I'd like to run, one emits an event and another consumes it. So ideally they both should be injected into the single Worker hosted service. How can I make this happen? I tried the code as below, but I'm getting: 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);
            }
        }
    }

Upvotes: 4

Views: 1702

Answers (1)

Rajan Panneer Selvam
Rajan Panneer Selvam

Reputation: 1299

Looks like the problem is initializing one of your class. Please check the contstructors of the Worker, Message Receiver and MessageForwarder class.

Also check this line, you are creating an instance of the interface.

services.AddSingleton<IWebhookMessageForwarder, IWebhookMessageForwarder>()

I tried the below code and it worked, which hosts a 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
{
}

Upvotes: 1

Related Questions