Introduction
With the new previews of dotnetcore there are new project templates. The new “worker” project template is the one which is being aimed at new microservices which need to run background processes or monitor processing on a queue etc.
On investigating I was curious to how to register services and if you’re used to ASP.Net Core then this should be straight forward, or is it?
Registering Services
The whole ethos, as far as I can make out, is the “hosting” model has been brought together and everything just uses a “host”. There is a web specific setup extension method but still an IHost
. Let’s take a quick look at the ASP.NET Core 3 program.cs contents.
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
As you can see this uses the new Host builder, however there is the familier UseStartup<Startup>
style registration inside the ConfigureWebHostDefaults
method that has been present for a few versions now.
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.AddHostedService<Worker>();
});
}
The “Worker” host builder looks familar but also different. Instead of registering a Startup
class and having a ConfigureServices
method declared the functionality is directly on the IHostBuilder
. This is how you register required services for your BackgroundService
.
The delegate required for this method is …
Action<HostBuilderContext, IServiceCollection> configureDelegate
… which allows services to be registered.
Simple Example
Using the IClock
abstraction I wrote about in Mocking the Clock this would be registered as follows …
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddSingleton<IClock, Clock>();
services.AddHostedService<Worker>();
});
The default Worker
class can then request the IClock
dependency through constructor injection and update the usage of the DateTimeOffset.Now
call from the default example as follows. Including the full worker class below to show full usage of the dependencies.
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IClock _clock;
public Worker(ILogger<Worker> logger, IClock clock)
{
_logger = logger;
_clock = clock;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", _clock.UtcNow);
await Task.Delay(1000, stoppingToken);
}
}
}
Conclusion
In this post we’ve looked briefly at the host builder changes between ASP.NET Core 2.2 and DotNet Core 3 (Preview 6) Worker host builder and how to register services onto the IServiceCollection
to allow for them to be used in the worker through dependency injection.
Any questions/comments then please contact me on Twitter @WestDiscGolf