Willis Willis - 2 months ago 25
C# Question

Autofac DI in parallel.foreach

I'm trying to use autofac with a parallel foreach. I've created a new Lifetime scope inside the parallel foreach. But when I access an injected EF repository from within the foreach it's throwing an object not set to an instance of an object exception.

using (var scope = container.BeginLifetimeScope())
{
Parallel.ForEach(items, item =>
{
using (var parallelScope = scope.BeginLifetimeScope())
{
var aDataService = parallelScope.Resolve<IaDataService>();
someProcessing(aDataService);
}
}
}

Answer

Application code should not have to know about creating scopes and having to deal with parallelization. So the Parallel.ForEach should be part of your composition root, and so should be any calls to BeginLifetimeScope. Besides this, don't use a lifetime scope as parent scope for creating new scopes in new threads; the new thread is a new context, and should create the scope directly from the container.

So this is code that should be part of your Composition Root:

Parallel.ForEach(items, item =>
{
     // Note I'm calling container.BeginLifetimeScope() inside the ForEach
     using (var parallelScope = container.BeginLifetimeScope())
     {
         var aDataService = parallelScope.Resolve<IaDataService>();
         aDataService.SomeProcessing();
     }
 }