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?
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>();