I have a problem with Autofac2 and MVC2. The problem is that I am trying to resolve a number of dependencies, where the root dependency is HttpRequestScoped. When I try to resolve my UnitOfWork (which is one-time), Autofac fails because the internal removal device is trying to add the UnitOfWork object to the internal removal list, which is null. Maybe I am registering my addictions with the wrong lifespan, but I have tried many different combinations with no luck. The only requirement I have is that MyDataContext lasts for the entire HttpRequest.
I posted a demo of the code to download here .
Autofac modules are configured in web.config
Global.asax.cs
protected void Application_Start()
{
string connectionString = "something";
var builder = new ContainerBuilder();
builder.Register(c => new MyDataContext(connectionString)).As<IDatabase>().HttpRequestScoped();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerDependency();
builder.RegisterType<MyService>().As<IMyService>().InstancePerDependency();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
_containerProvider = new ContainerProvider(builder.Build());
IoCHelper.InitializeWith(new AutofacDependencyResolver(_containerProvider.RequestLifetime));
ControllerBuilder.Current.SetControllerFactory(new AutofacControllerFactory(ContainerProvider));
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
AutofacDependencyResolver.cs
public class AutofacDependencyResolver
{
private readonly ILifetimeScope _scope;
public AutofacDependencyResolver(ILifetimeScope scope)
{
_scope = scope;
}
public T Resolve<T>()
{
return _scope.Resolve<T>();
}
}
IoCHelper.cs
public static class IoCHelper
{
private static AutofacDependencyResolver _resolver;
public static void InitializeWith(AutofacDependencyResolver resolver)
{
_resolver = resolver;
}
public static T Resolve<T>()
{
return _resolver.Resolve<T>();
}
}
UnitOfWork.cs
public interface IUnitOfWork : IDisposable
{
void Commit();
}
public class UnitOfWork : IUnitOfWork
{
private readonly IDatabase _database;
public UnitOfWork(IDatabase database)
{
_database = database;
}
public static IUnitOfWork Begin()
{
return IoCHelper.Resolve<IUnitOfWork>();
}
public void Commit()
{
System.Diagnostics.Debug.WriteLine("Commiting");
_database.SubmitChanges();
}
public void Dispose()
{
System.Diagnostics.Debug.WriteLine("Disposing");
}
}
MyDataContext.cs
public interface IDatabase
{
void SubmitChanges();
}
public class MyDataContext : IDatabase
{
private readonly string _connectionString;
public MyDataContext(string connectionString)
{
_connectionString = connectionString;
}
public void SubmitChanges()
{
System.Diagnostics.Debug.WriteLine("Submiting Changes");
}
}
MyService.cs
public interface IMyService
{
void Add();
}
public class MyService : IMyService
{
private readonly IDatabase _database;
public MyService(IDatabase database)
{
_database = database;
}
public void Add()
{
}
}
HomeController.cs
public class HomeController : Controller
{
private readonly IMyService _myService;
public HomeController(IMyService myService)
{
_myService = myService;
}
public ActionResult Index()
{
using(var unitOfWork = UnitOfWork.Begin())
{
_myService.Add();
unitOfWork.Commit();
}
return View();
}
public ActionResult About()
{
return View();
}
}