I've just switched over to Autofac and it seems to be working well. However I've received one disconcerting error message whilst debugging the application. However I've since not been able to replicate it. I think this has something to do with a multithreading race condition.
Autofac.Core.DependencyResolutionException: An exception was thrown while executing a resolve operation. See the InnerException for details. ---> An item with the same key has already been added. (See inner exception for details.) ---> System.ArgumentException: An item with the same key has already been added.
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id, Func`1 creator)
at Autofac.Core.Resolving.InstanceLookup.Execute()
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)
at Autofac.Core.Resolving.ResolveOperation.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)
--- End of inner exception stack trace ---
at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)
at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Type serviceType, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable`1 parameters)
at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context)
at Tuna.TunaKernel.Get[T]() in S:\Tuna\TunaKernel.cs:line 32
In case you're wondering what TunaKernel looks like...
using Autofac;
using Autofac.Core;
using System.Collections.Generic;
namespace Tuna
{
/// <summary>
/// A class used for providing instances of classes to Tuna applications
/// </summary>
/// <remarks>Wrapper around Autofac IOC solution</remarks>
public class TunaKernel : ITunaKernel
{
ILifetimeScope _container;
/// <summary>
/// Prevents a default instance of the <see cref="TunaKernel"/> class from being created.
/// </summary>
/// <param name="modules">The modules.</param>
public TunaKernel(ILifetimeScope container)
{
_container = container;
}
/// <summary>
/// Gets an instance of T
/// </summary>
/// <typeparam name="T">The object to get an instance of</typeparam>
/// <returns></returns>
public T Get<T>()
{
return _container.Resolve<T>();
}
}
}
The binding for the item was
builder.RegisterType<EditProgramHelper>().As<IEditProgramHelper>().InstancePerRequest();
And yes I realise using the scope directly like this is not advised, however I'm dealing with a large amount of code that is already written.