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.
InstancePerLifetimeScope means a new instance of the service will be created for every lifetime scope which asks for your service. Each web request gets its own fresh lifetime scope, so in practice, more often than not, these two will do the exact same thing.
Autofac is an addictive IoC container for . NET. It manages the dependencies between classes so that applications stay easy to change as they grow in size and complexity. This is achieved by treating regular . NET classes as components.
From Visual Studio, you can get it via NuGet. The package name is Autofac. Alternatively, the NuGet package can be downloaded from the GitHub repository (https://github.com/autofac/Autofac/releases).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With