Migrating from Simple Injector to Autofac

Autofac is a second-generation DI container which API is directly based on .NET 3.5 and modern language features. It has a well thought, consistent API, and migration to Autofac is pretty straightforward.

Website http://autofac.org
Download http://code.google.com/p/autofac/downloads/list
Supported platforms .NET 3.5 (and up), Silverlight 3 (and up)
Code samples based on version 2.4.5

Core differences with Simple Injector

  1. Autofac separates the registration process from resolving by defining a ContainerBuilder class that generates an Autofac.IContainer.
  2. By default, concrete instances can not be resolved without registration. This behavior can be overridden.
  3. The registration methods lack generic type constraints, which won’t fail at compile time, but at run time. It is possible to define an extension method that fixes this.
  4. Autofac will track every IDisposable component that it creates, no matter how that instance is requested.

Code Samples

The following section contains code snippets that show how to resolve and register instances with the Simple Injector on the left-hand side, and equivalent snippets for Autofac on the right-hand side.

Resolving Instances

Simple Injector Autofac
container.GetInstance<IService>(); container.Resolve<IService>();
container.GetInstane(typeof(IService)); container.Resolve(typeof(IService));
IEnumerable<IFilter> filters = container.GetAllInstances<IFilter>(); IEnumerable<IFilter> filters =
    container.Resolve<IEnumerable<IFilter>>();
IEnumerable<object> filters = container
    .GetAllInstances(typeof(IFilter));
Type collectionType = typeof(IEnumerable<>) 
    .MakeGenericType(typeof(IFilter));

IEnumerable
filters = (IEnumerable)
   
container.Resolve(collectionType);

Registration

Registration with a transient lifetime.
Simple Injector Autofac
// Optional. Concrete instances can be
// resolved without registration
container.Register<RealService>();
// Required. Concrete instances will not
// be resolved without registration.
builder.RegisterType<RealService>();
container.Register<IService, RealService>(); builder.RegisterType<RealService>() 
    .As<IService>();
container.Register<IService>(() =>

    var logger =
        container.GetInstance<ILogger>(); 
    return new RealService(logger);
});
builder.Register<IService>(container =>

    var logger =
        container.Resolve<ILogger>(); 
    return new RealService(logger);
});
Registration with a singleton lifetime.
Simple Injector Autofac
container.RegisterSingle<RealService>(); builder.RegisterType<RealService()
    .SingleInstance();
container
    .RegisterSingle<IService, RealService>();
builder.RegisterType<RealService>()
    .As<IService>().SingleInstance();
container.RegisterSingle<IService>(() =>
{  
  var log = container.GetInstance<ILogger>();  
  return new RealService(log);
});
builder.Register<IService>(container =>

    var log = container.Resolve<ILogger>(); 
    return new RealService(log);
}).SingleInstance();
container.RegisterSingle<IService>( 
  new RealService(new ConsoleLogger()));
builder.Register<IService>(container =>

    return new RealService(new ConsoleLogger());
}).SingleInstance();
container.RegisterAll<IFilter>( 
    new XssInjectionFilter(), 
    new SqlInjectionFilter(), 
    new SmartFilter()
);
builder.RegisterType<XssInjectionFilter>()
    .As<IFilter>().SingleInstance();
builder.RegisterType<SqlInjectionFilter>()
    .As<IFilter>().SingleInstance();
builder.RegisterType<SmartFilter>()
    .As<IFilter>().SingleInstance();
IEnumerable<IFilter> filters = 
    FilterProvider.GetFilters();
container.RegisterAll<IFilter>(filters);
IEnumerable<IFilter> filters =
    FilterProvider.GetFilters();
builder.Register<IEnumerable<IFilter>>(c =>
    filters).SingleInstance();
container.RegisterInitializer<ICommand>(cmd =>

    cmd.SendAsync = true
    cmd.Logger =
        container.GetInstance<ILogger>();
});
builder.RegisterType<ICommand>()
    .OnActivating(e =>
{
    e.Instance.SendAsync = true;
    e.Instance.Logger = 
        e.Context.Resolve<ILogger>();
});

Advanced Scenarios

The SimpleInjector.Extensions.dll contains extension methods for the Container class that enable many advanced scenario’s. The section below how the registrations done with the Extensions library maps to those of Autofac.

Registration using the non-generic API.
Simple Injector Autofac
container.Register(typeof(IService),
    typeof(RealService));
builder.Register(typeof(RealService))
    .As(typeof(IService));
container.RegisterAll<IFilter>(
    from asm in AppDomain.CurrentDomain
        .GetAssemblies()
    from type in asm.GetExportedTypes()
    where !type.IsAbstract
    where typeof(IFilter).IsAssignableFrom(type)
    select type);
builder.RegisterAssemblyTypes(
    AppDomain.CurrentDomain.GetAssemblies())
    .Where(type => type.IsPublic)
    .As<IFilter>();
Batch registration of generic interfaces
Simple Injector Autofac
container.RegisterManyForOpenGeneric(
    typeof(IHandler<>),
    typeof(IHandler<>).Assembly);
builder.RegisterAssemblyTypes(
    typeof(IHandler<>).Assembly)
    .AsClosedTypesOf(typeof(IHandler<>));
container.RegisterManyForOpenGeneric(
    typeof(IHandler<>),
    AppDomain.CurrentDomain.GetAssemblies());
builder.RegisterAssemblyTypes(
    AppDomain.CurrentDomain.GetAssemblies())
    .AsClosedTypesOf(typeof(IHandler<>));
var asm = typeof(IHandler<>).Assembly;

container.RegisterManyForOpenGeneric(
    typeof(IHandler<>),
    from type in asm.GetTypes()
    where !type.IsAbstract
    where type.Name.EndsWith("Handler")
    select type);
var asm = typeof(IHandler<>).Assembly;

builder.RegisterAssemblyTypes(asm)
    .Where(t => t.Name.EndsWith("Handler"))
    .AsClosedTypesOf(typeof(IHandler<>));
Mapping of open generic types to an open generic implementation
Simple Injector Autofac
container.RegisterOpenGeneric(
    typeof(IValidator<>),
    typeof(NullValidator<>));
builder.RegisterGeneric(
    typeof(NullValidator<>))
    .As(typeof(IValidator<>));

 

typeof(IFilter).IsAssignableFrom(type)

Last edited Oct 6, 2012 at 12:51 PM by dot_NET_Junkie, version 23