Notes from an Autofac Upgrade (1.4 - 2.2)

Autofac is an simple, elegant and powerful IoC container written by Nicholas Blumhardt, Rinat Abdullin and friends.  Version 1 was release in early 2008 and version 2 was released earlier this year with many new features.  and If you are looking for an IoC container, I highly recommend it.

Autofac underwent some fairly significant surgery as part of the 2.x release in order to “simplify and streamline” usage.  The Autofac wiki lists the key changes for upgrading users.  Recently, I migrated a project from Autofac 1.4 to Autofac 2.2.  The changes were done in less than a day and so far we’ve not had any issues.  What follows are my “real world” notes on the changes I made. 

Changes Related to the Core Autofac Bits

  • Updated component registration lifetime calls (see New Lifetime/Sharing Terminology):
    • FactoryScoped() to InstancePerDependency()
    • ContainerScoped() to InstancePerLifetimeScope()
    • SingletonScoped() to SingleInstance()
  • Updated using statements for Module usages.  Module has moved from from Autofac.Builder to Autofac (see Namespace Changes).
  • We were using the ComponentActivator delegate type in some custom extension method declarations.  We have changed these to Func<IComponentContext, TWeAreCreating> as the new Register overloads take this or a Func<IComponentContext, IEnumerable<Parameter>, TWeAreCreating>.
  • Updated component registrations that require property injection.
    From this:
    ...As<IFoo>.OnActivating(ActivatingHandler.InjectProperties)
    To this:
    ...As<IFoo>.PropertiesAutowired(false)//false for no circular dependency.
  • The Register methods now only accept delegates.  If you want to register an instance you need to use RegisterInstance.  While migrating to Autofac 2.2 this change highlighted at least one incorrect registration (see Separation of Registration Overloads).
  • Removed calls to .MemberOf<IEnumerable<TWhatever>>() as resolving collections is supported by default (I know we could have registered the collection module in 1.x but we discovered a defect in it which Nick confirmed).  See Collection Support (“Resolve All”).
    • Removed custom extension methods for registering collections (.RegisterCollection<IFoo>) to using default collection behaviour.
  • Updated OnActivating calls arg from EventHandler<ActivatingEventArgs> to Action<IActivatingEventArgs<TFoo>>.
  • Named("RegistrationName") had been replaced by Named<T>("RegistrationName") as naming now requires type information too (see Changes to Named Services).

Changes Related to the Contrib and Integration Bits

  • AutofacContrib.CommonServiceLocator - For some reason (I did it, but can't remember why) we had the source for AutofacServiceLocator in our project (this is an Autofac implementation of ServiceLocatorImplBase from the CommonServiceLocator project).  Deleted this (nice!) and added a reference to AutofacContrib.CommonServiceLocator.dll (taken from AutofacContrib).  Updated the construtor calls with RequestLifetime.
  • AutofacContrib.Moq - Removed our AutoMockContainer implementation and moved to the AutoMock implementation in the Autofac.Contrib assembly AutofacContrib.Moq.dll.
    NOTE:  We had a lot of test dependencies on AutoMockContainer and the AutoMock type is quite different.  We found it easier to create an Adapter called AutoMockContainer that adapted AutoMock.
  • Autofac.Integration.Web - The member IContainer IContainerProvider.RequestContainer has been replaced with ILifetimeScope IContainerProvider.RequestLifetime.  See the "Lifetime and Scope" section.