January 26th, 2017

Comparing ASP.NET Core IoC container service lifetimes with Autofac IoC container instance scopes

Cesar De la Torre
Principal Program Manager

DI_NET

In ASP.NET Core you can use the simple built-in IoC container or you can also plug any other more advanced IoC container like Autofac.

When plugin an external container like Autofac, you can still use ASP.NET Core methods like services.AddTransient<> or services.AddSingleton<> or you can also use the more granular methods in Autofac based on its instance scopes, which offer a larger set of possibilities.

Anyways, because I’m working “from both sides”, I wanted to have clear a comparison of each type and how are they exactly called from each API..

So here it is a convenient table that I just created:

ASP.NET Core

Built-in IoC container

Autofac

IoC container

Description

ServiceLifetime.Transient

services.AddTransient<,>

InstancePerDependency()

A unique instance will be returned from each object request.

ServiceLifetime.Scoped

services.AddScope<,>

In ASP.NET Core applications a scope is created around each server request.

But it could be used as plain Scoped (non related to Http requests) if using DI out of ASP.NET Core

InstancePerLifetimeScope()

 

A component with per-lifetime scope will have at most a single instance per nested lifetime scope.

This is useful for objects specific to a single unit of work that may need to nest additional logical units of work. Each nested lifetime scope will get a new instance of the registered dependency.

For example, this type of lifetime scope is useful for Entity Framework DbContext objects (Unit of Work pattern) to be shared across the object scope so you can run transactions across multiple objects.

ServiceLifetime.Scoped

services.AddScope<,>

In ASP.NET Core applications a scope is created around each server request, so it will work similar to InstancePerRequest, in this case.

InstancePerRequest()

Application types like ASP.NET Core naturally lend themselves to “request” type semantics. You have the ability to have a sort of “singleton per request.”

Instance per request builds on top of instance per matching lifetime scope by providing a well-known lifetime scope tag, a registration convenience method, and integration for common application types. Behind the scenes, though, it’s still just instance per matching lifetime scope.

ServiceLifetime.Singleton

services.AddSingleton<,>

SingleInstance()

One instance is returned from all requests in the root and all nested scopes

NO

InstancePerMatchingLifetimeScope()

you have the ability to “tag” or “name” the scope. A component with per-matching-lifetime scope will have at most a single instance per nested lifetime scope that matches a given name. This allows you to create a sort of “scoped singleton”

NO

InstancePerOwned()

The Owned<T> implicit relationship type creates new nested lifetime scopes. It is possible to scope dependencies to the owned instance using the instance-per-owned registrations.

NO

Thread Scope

(based on lifetime scopes)

Autofac can enforce that objects bound to one thread will not satisfy the dependencies of a component bound to another thread. While there is not a convenience method for this, you can do it using lifetime scopes.

 

Note that ASP.NET Core only uses the three more common types of instance life time:

– Transient, PerRequest/Scoped and Singleton.

References:

Service Lifetime in .NET Core: https://github.com/aspnet/DependencyInjection/blob/dev/src/Microsoft.Extensions.DependencyInjection.Abstractions/ServiceLifetime.cs

Instance Scopes in Autofac: http://docs.autofac.org/en/latest/lifetime/instance-scope.html

Author

Cesar De la Torre
Principal Program Manager

Principal Program Manager at the Azure team.

0 comments

Discussion are closed.