Reputation: 1813
I am trying to understand lifetime scopes in Autofac IOC and have the following question.
Assume we have class:
public class TestMemLeak
{
SomeDisposableContext cn;
public TestMemLeak(SomeDisposableContext context)
{
cn = context;
}
}
where the injected dependency SomeDisposableContext implements IDisposable.
In an MVC application I get a memory leak when resolving TestMemLeak object if SomeDisposableContext is registered as InstancePerDependency (default option). The leak is gone if I register it as InstancePerRequest or InstancePerLifetimeScope.
I don't understand why InstancePerLifetimeScope fixes the leak. My understanding is that if we resolve dependency from root then InstancePerLifetimeScope should behave in same way as InstancePerDependency, and the solution to problem would be to pass ILifetimeScope to TestMemLeak class and resolve the dependency using lifetime scope. Why is this assumption wrong and what is the difference between InstancePerRequest and InstancePerLifetimeScope in MVC app scenario (apart from InstancePerRequest looks for specific 'httpRequest' lifetime scope)? When should I use InstancePerRequest? It would be great if someone could explain this especially from memory leaks perspective.
Upvotes: 6
Views: 6395
Reputation: 19630
As described in the documentation, InstancePerLifetimeScope
works for nested resolves. So it means that in your case one object was instantiated for your HTTP request and it gets its dependencies injected and they are all resolved within the same scope. This is basically done by Autofac MVC integration, it is known as BeginLifetimeScope
with the HTTP scope tag.
In case your dependency will be instantiated somewhere else, not within the nested resolution three, it will be outside of the lifetime scope and will not be disposed.
InstancePerRequest
however is nothing more than the InstancePerMatchingLifetimeScope
with predefined tag constant MatchingScopeLifetimeTags.RequestLifetimeScopeTag
. Therefore, your dependency does not need to be instantiated inside the nested lifetime scope resolution, it will be enough for the scope with this tag to be open to get the instance attached to this scope.
Upvotes: 5