To make it simple,
Let say I have a gRPC service:
At Startup.cs
, I added the dependencies the services needed.
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
// Add dependencies
services.AddSingleton<IDoSomething1, DoSomething1>();
services.AddSingleton<IDoSomething2, DoSomething2>();
services.AddSingleton<IDoSomething3, DoSomething3>();
...
}
It is working fine. But now, I want to do have some jobs running at the background (like querying a DB/another service for some updates).
Hence, I do something like below (using Timer + BackgroundWorker) at Program.cs
.
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
...
// Use the Startup class as shown above, so that I can using the dependencies added
webBuilder.UseStartup<Startup>();
}
public static void Main(string[] args)
{
// CreateHostBuilder -> Startup -> Dependencies added
using (var app = CreateHostBuilder(args).Build())
{
app.Start();
// Use Timer + BackgroundWorker here
BackgroundWorker backgroundWorker = new();
backgroundWorker.DoWork += BackgroundWorker_DoWork;
System.Timers.Timer timer = new();
timer.Interval = 2000;
timer.Enabled = true;
timer.Elapsed += (object sender, System.Timers.ElapsedEventArgs args) => backgroundWorker.RunWorkerAsync(app.Services);
app.WaitForShutdown();
}
}
private static void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
IServiceProvider sp = (IServiceProvider)e.Argument;
// Need to call GetRequiredService explicitly instead of automatically done by automatic constructor dependency injection
IDoSomething1 doSomething1 = sp.GetRequiredService<IDoSomething1>();
IDoSomething2 doSomething2 = sp.GetRequiredService<IDoSomething2>();
IDoSomething3 doSomething3 = sp.GetRequiredService<IDoSomething3>();
...
}
Although the code above should work, it does not seems elegant to me, because it needs to call GetRequiredService explicitly instead of automatically done by automatic constructor dependency injection like the gRPC service class.
Is any better way to do so? I mean something like app.AddBackgroundJob(...)
?