Warm tip: This article is reproduced from serverfault.com, please click

How to inject a reference to a specific IHostedService implementation?

发布于 2018-07-09 21:08:19

My web app has a background service that listens to a service bus. Based on the docs, it looks like the built-in way to run a background service is to implement IHostedService.

So I have some code that looks like this:

public class ServiceBusListener : IMessageSource<string>, IHostedService
{
    public virtual event ServiceBusMessageHandler<string> OnMessage = delegate { };

    public Task StartAsync(CancellationToken cancellationToken)
    {
        // run the background task...
    }

    // ... other stuff ...
}

The service is then registered in Startup.cs with:

services.AddSingleton<IHostedService, ServiceBusListener>();

Once I update to ASP.NET 2.1 I can use the new convenience method:

services.AddHostedService<ServiceBusListener>();

But I believe the two are functionally equivalent.

The complication: my web app has multiple implementations of IHostedService (specifically, different instances of service bus listeners).

The question: how can I have some other component get a reference to a specific hosted service implementation (my service bus listener)? In other words, how do I get a specific instance injected into a component?

Use case: my background service listens for service bus messages and then re-publishes messages as .NET events (in case you're wondering, the consuming code deals with the threading issues). If the event is on the background service, then subscribers need to get a reference to the background service to be able to subscribe.

What I've tried: if I do the obvious thing and declare ServiceBusListener as a dependency to be injected into a different component, my startup code throws a "Could not resolve a service of type" exception.

Is it even possible to request a specific implementation of a IHostedService? If not, what's the best workaround? Introduce a third component that both my service and the consumer can reference? Avoid IHostedService and run the background service manually?

Questioner
Michael Kropat
Viewed
0
jjxtra 2020-11-23 23:46:07

None of the complexity in the other answers is needed as of .net core 3.1. If you don't need to get a concrete reference to your class from another class, simply call:

services.AddHostedService<MyHostedServiceType>();

If you must have a concrete reference, do the following:

services.AddSingleton<IHostedService, MyHostedServiceType>();