Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autofac: What is the difference between InstancePerRequest and InstancePerLifetimeScope in an MVC app

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.

like image 879
lekso Avatar asked Jul 15 '16 11:07

lekso


People also ask

What is InstancePerLifetimeScope?

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.

What is Autofac container?

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.

How do I get Autofac containers?

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).


1 Answers

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.

like image 167
Alexey Zimarev Avatar answered Oct 20 '22 22:10

Alexey Zimarev