What's new? | Help | Directory | Sign in
Google
autofac
An addictive .NET IoC container
  
  
  
  
    
Search
for
Updated May 26, 2008 by nicholas.blumhardt
BestPractices  
Guidance for using Autofac effectively.

Manage Object Lifetimes using Inner Containers

Autofac is designed to track and dispose of resources for you. To ensure this happens, make sure that long-running applications are partitioned into requests or transactions that each resolve instances through their own inner container. The RequestContainer in the ASP.NET Integration is an example of this technique.

Prefer Delegate Registrations

When registering a batch of components by type, it is perfectly acceptable to use the reflection API. Delegate (expression) registrations are encouraged at other times since they provide clearer expression of intent, better performance and a better debugging experience.

Use As() instead of Casting

Autofac infers implementation type from the expressions you use to register components:

builder.Register(c => new Foo()).As<IFoo>();

...makes the type Foo available to any extensions that may rely upon it, while the equivalent:

// Works, but avoid this
builder.Register(c => (IFoo)new Foo());

or:

// Works, but avoid this
builder.Register<IFoo>(c => new Foo());

...do not.

Avoid Registering Components in Inner Containers

Inner containers can be used to manage the direction of dependencies between components in the inner and outer containers. This happens naturally in hierarchies two containers deep.

Hierarchies three or more instances deep will sometimes wish to 'pin' a component's lifecycle to a container in the middle of the hierarchy. This could be achieved by registering the component as a singleton in the middle containers when they're created.

There are problems with this approach, however. The first is that extensions registered in the root (outer) container will not be applied to components registered in the inner container. The second is that any caching that can be done to improve the performance of activation in the component will not be applied.

Registering components in inner containers can still be useful, but the encouraged means to achieve this goal is to use tags.

Minimise Unnecessary Tag Usage

Despite tags being an effective way to manage scope in a container hierarchy, any modules that use them will have a dependency on the tag structure of the application in which they're being deployed. This makes it harder to reuse modules in different application structures, e.g. a web application and a console application.

While this is no different to the classical problem of a facility using a lifecycle (e.g. 'request') that does not apply in all environments, keeping this kind of implicit coupling to a minimum is advised.

Use Constructor Injection whenever Possible

The concept of using constructor injection for required dependencies and property injection for optional dependencies is quite well known. An alternative, however, is to use the 'Null Object' or 'Special Case' pattern to provide default, do-nothing implementations for the optional service. This prevents the possibility of special-case code in the implementation of the component (e.g. if (Logger != null) Logger.Log("yuck");)

Don't Pass the Container Around

Giving components access to the container, or storing it in a public static property, or making functions like Resolve() available on a global 'IoC' class defeats the purpose of using dependency injection. Such designs have more in common with the Service Locator pattern.

If components have a dependency on the container, look at how they're using the container to retrieve services, and add those services to the component's (dependency injected) constructor arguments instead.

Use generated or hand-coded factories for components that need to instantiate other components.

Register Components from Least to Most Specific

Autofac overrides component registrations by default. This means that an application can register all of its default components, then read an associated .config file to override any that have been customised for the deployment environment.


Sign in to add a comment