==============================
Controlling Scope and Lifetime
==============================
A great place to start learning about Autofac scope and lifetime is in `Nick Blumhardt's Autofac lifetime primer `_. There's a lot to digest, though, and a lot of intermixed concepts there, so we'll try to complement that article here.
You may recall from the :doc:`registration topic <../register/registration>` that you add **components** to the container that implement **services**. You then end up :doc:`resolving services <../resolve/index>` and using those service instances to do your work.
The **lifetime** of a service is how long the service instance will live in your application - from the original instantiation to :doc:`disposal `. For example, if you "new up" an object that implements `IDisposable `_ and then later call ``Dispose()`` on it, the lifetime of that object is from the time you instantiated it all the way through disposal (or garbage collection if you didn't proactively dispose it).
The **scope** of a service is the area in the application where that service can be shared with other components that consume it. For example, in your application you may have a global static singleton - the "scope" of that global object instance would be the whole application. On the other hand, you might create a local variable in a ``for`` loop that makes use of the global singleton - the local variable has a much smaller scope than the global.
The concept of a **lifetime scope** in Autofac combines these two notions. Effectively, a lifetime scope equates with a unit of work in your application. A unit of work might begin a lifetime scope at the start, then services required for that unit of work get resolved from a lifetime scope. As you resolve services, Autofac tracks disposable (``IDisposable``) components that are resolved. At the end of the unit of work, you dispose of the associated lifetime scope and Autofac will automatically clean up/dispose of the resolved services.
**The two important things lifetime scopes control are sharing and disposal.**
- **Lifetime scopes are nestable and they control how components are shared.** For example, a "singleton" service might be resolved from a root lifetime scope while individual units of work may require their own instances of other services. You can determine how a component is shared by :doc:`setting its instance scope at registration `.
- **Lifetime scopes track disposable objects and dispose of them when the lifetime scope is disposed.** For example, if you have a component that implements ``IDisposable`` and you resolve it from a lifetime scope, the scope will hold onto it and dispose of it for you so your service consumers don't have to know about the underlying implementation. :doc:`You have the ability to control this behavior or add new disposal behavior if you choose. `
As you work in your application, it's good to remember these concepts so you make the most efficient use of your resources.
**It is important to always resolve services from a lifetime scope and not the root container.** Due to the disposal tracking nature of lifetime scopes, if you resolve a lot of disposable components from the container (the "root lifetime scope"), you may inadvertently cause yourself a memory leak. The root container will hold references to those disposable components for as long as it lives (usually the lifetime of the application) so it can dispose of them. :doc:`You can change disposal behavior if you choose `, but it's a good practice to only resolve from a scope. If Autofac detects usage of a singleton or shared component, it will automatically place it in the appropriate tracking scope.
Let's look at a web application as a more concrete example to illustrate lifetime scope usage. Say you have the following scenario:
- You have a global singleton logging service.
- Two simultaneous requests come in to the web application.
- Each request is a logical "unit of work" and each requires its own order processing service.
- Each order processing service needs to log information to the logging service.
In this scenario, you'd have a root lifetime scope that contains the singleton logging service and you'd have one child lifetime scope per request, each with its own order processing service::
+---------------------------------------------------+
| Autofac Container |
| Root Lifetime Scope |
| |
| Logging Service |
| (shared across all requests) |
| |
| +----------------------+ +----------------------+ |
| | First Request Scope | | Second Request Scope | |
| | | | | |
| | Order Processor | | Order Processor | |
| +----------------------+ +----------------------+ |
+---------------------------------------------------+
When each request ends, the request lifetime scope ends and the respective order processor gets disposed. The logging service, as a singleton, stays alive for sharing by future requests.
You can dive deeper on lifetime scopes in `Nick Blumhardt's Autofac lifetime primer `_.
**Additional lifetime scope topics to explore:**
.. toctree::
working-with-scopes.rst
instance-scope.rst
captive-dependencies.rst
disposal.rst
events.rst
startup.rst