We are in the process of migrating a .net framework web jobs implementation to dotnet core. I'm using the documented extension method (IHostBuilder.ConfigureServices) on IHostBuilder to register dependencies with the scopes that seem fit, i.e., scoped, because most of the time I want an instance per web job invocation.
In the unit of work implementation that we use, the Entity Framework DbContext is disposed when the unit of work completes. In local development, and this is the issue that leads to this question, I bump into the issue that a second trigger (the web job is triggered via a ServiceBusTrigger) reuses the same instances of my dependencies, while they are properly registered on the IServiceCollection via the regular AddScoped<,> API. In my scenario, this manifests itself a DisposedObjectException on the DbContext.
While investigating this, I found that all scoped services are reused over invocations, which leads to the question whether you have to do the scoping differently in Azure Webjobs? Is this a local development thing only?
So, in pseudo code, this is how stuff is implemented:
// Program.cs
public static async Task Main()
{
var builder = new HostBuilder();
builder.ConfigureLogging((ctx, loggingBuilder) => { /* ... */});
builder.ConfigureWebJobs(webJobsBuilder => {
// DO STUFF
webJobsBuilder.AddServiceBus(options => { /* ... */ });
});
builder.ConfigureServices(services => {
services.AddScoped<IService, ServiceImplementation>();
// ...
services.AddScoped<IContextFactory, ContextFactoryImplementation>();
// ...
});
var host = builder.Build();
using(host)
{
await host.RunAsync();
}
}
And the unit of work is basically:
public class UnitOfWork: IUnitOfWork
{
public UnitOfWork(DbContext context)
{
// ...
}
public void Commit()
{
dbContext.SaveChanges();
}
public void Dispose()
{
...
}
public void Dispose(bool disposing)
{
...
dbContext?.Dispose();
dbContext = null;
}
}
Thanks!