Lately I've been creating it as an IHostedService
if it needs initialization, because to me it seems more logical to let the initialization be handled by the service itself rather than outside of it.
You can even use a BackgroundService
instead of IHostedService
as it's pretty similar and it only needs the implementation of ExecuteAsync
Here's the documentation for them
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services
An example of how to add the service so you can inject it directly:
services
.AddHostedService<MyService>()
.AddSingleton<MyService>(x => x
.GetServices<IHostedService>()
.OfType<MyService>()
.First());
Example of a simple service:
public class MyService : IHostedService
{
// This function will be called automatically when the host `starts`
public async Task StartAsync(CancellationToken cancellationToken)
{
// Do initialization logic
}
// This function will be called automatically when the host `stops`
public Task StopAsync(CancellationToken cancellationToken)
{
// Do cleanup if needed
return Task.CompletedTask;
}
}
Some extension methods I created later on because i needed to use the same pattern again
public static class HostedServiceExtensions
{
public static IServiceCollection AddHostedServiceAsService<T>(this IServiceCollection services) where T : class, IHostedService
=> services.AddHostedService<T>().AddSingleton(x => x.GetServices<IHostedService>().OfType<T>().First());
public static IServiceCollection AddHostedServiceAsService<T>(this IServiceCollection services, Func<IServiceProvider, T> factory) where T : class, IHostedService
=> services.AddHostedService(factory).AddSingleton(x => x.GetServices<IHostedService>().OfType<T>().First());
}
Used like
services.AddHostedServiceAsService<MyService>();
// Or like this if you need a factory
services.AddHostedServiceAsService<MyService>(x => new MyService());