I was able to resolve this problem. I'm not entirely clear why dispose was being called on SimpleInjectorWebApiDependencyResolver
, but here's what I figured out:
The BAD Dependency resolver implementation was a copy of the one listed here:
public sealed class SimpleInjectorWebApiDependencyResolver : IDependencyResolver
{
private readonly Container container;
public SimpleInjectorWebApiDependencyResolver(Container container)
{
this.container = container;
}
public IDependencyScope BeginScope()
{
return this;
}
public object GetService(Type serviceType)
{
return ((IServiceProvider)this.container).GetService(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return this.container.GetAllInstances(serviceType);
}
public void Dispose()
{
}
}
I noticed there is a bit different copy in the source code I downloaded here.
public sealed class SimpleInjectorWebApiDependencyResolver : IDependencyResolver
{
private readonly Container container;
private readonly Scope scope;
public SimpleInjectorWebApiDependencyResolver(Container container) : this(container, beginScope: false)
{
Requires.IsNotNull(container, "container");
}
private SimpleInjectorWebApiDependencyResolver(Container container, bool beginScope)
{
this.container = container;
if (beginScope)
{
this.scope = container.BeginExecutionContextScope();
}
}
IDependencyScope IDependencyResolver.BeginScope()
{
return new SimpleInjectorWebApiDependencyResolver(this.container, beginScope: true);
}
object IDependencyScope.GetService(Type serviceType)
{
if (!serviceType.IsAbstract && typeof(IHttpController).IsAssignableFrom(serviceType))
{
return this.container.GetInstance(serviceType);
}
return ((IServiceProvider)this.container).GetService(serviceType);
}
IEnumerable<object> IDependencyScope.GetServices(Type serviceType)
{
return this.container.GetAllInstances(serviceType);
}
void IDisposable.Dispose()
{
if (this.scope != null)
{
this.scope.Dispose();
}
}
}
After switching over to this version everything worked. I still have potential issues CallContext.LogicalGetData and Nested Execution Contexts, as @Steven was kind enough to point out in the comments. So use this solution at your own risk.