How to plug my Autofac container into ASP. NET Identity 2.1 How to plug my Autofac container into ASP. NET Identity 2.1 asp.net asp.net

How to plug my Autofac container into ASP. NET Identity 2.1


I'm starting from an out-of-the-box MVC5 installation and using AutoFac as an IoC container. It sounds like I am trying to acheive a similar goal as you, so let me explain what I've done. As a disclaimer, I am fairly new to using IoC and to Identity.

I believe the IOwinContext is unnecessary in a role as an IoC if you are using your own - I switched over to registering my ApplicationUserManager with AutoFac. To achieve this I had to:

Remove CreatePerOwinContext lines from Startup.Auth since I'll register ApplicationDbContext and ApplicationUserManager in AutoFac.

//app.CreatePerOwinContext(ApplicationDbContext.Create);//app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

Modify the ApplicationUserManager constructor arguments and included everything from the Create function.

public ApplicationUserManager(IUserStore<ApplicationUser> store, IdentityFactoryOptions<ApplicationUserManager> options)        : base(store){    //all the code from the 'Create' function here, using `this` for `manager`}

Set the AccountController to have a single constructor taking an ApplicationUserManager as an argument and scrapped the UserManager property that grabs the ApplicationUserManager from the OwinContext.

private ApplicationUserManager _userManager; //every thing that needs the old UserManager property references this nowpublic AccountController(ApplicationUserManager userManager) {    _userManager = userManager;}

Register everything with AutoFac, including an instance of IdentityFactoryOptions.

var x = new ApplicationDbContext();builder.Register<ApplicationDbContext>(c => x);builder.Register<UserStore<ApplicationUser>>(c => new UserStore<ApplicationUser>(x)).AsImplementedInterfaces();builder.Register<IdentityFactoryOptions<ApplicationUserManager>>(c => new IdentityFactoryOptions<ApplicationUserManager>(){    DataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("ApplicationName")});builder.RegisterType<ApplicationUserManager>();

That's the rough summary. I may have missed a couple of other tweaks I had to do along the way.


Ben's answer gets the general idea right, but it manually instantiates the DbContext and uses this instance when registering the rest of the types. IMO, that's a bad idea (one shouldn't use the same eternal db context for ALL requests).

Derek's comment is a big improvement, but it doesn't pass the database context to the user store, resulting in errors such as "The entity type ApplicationUser is not part of the model for the current context.".

I've included my code below, for reference - it's really similar to Derek's.

builder.RegisterType<MyApplicationContext>().AsSelf().InstancePerRequest()//...builder.RegisterType<ApplicationUserManager>().AsSelf().InstancePerRequest();builder.RegisterType<ApplicationSignInManager>().AsSelf().InstancePerRequest();builder.Register(c => new UserStore<ApplicationUser>(c.Resolve<MyApplicationContext>())).AsImplementedInterfaces().InstancePerRequest();builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).As<IAuthenticationManager>();builder.Register(c => new IdentityFactoryOptions<ApplicationUserManager>{    DataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("Application​")}); 


For reference here's how you can wire everything up using Unity:

var container = new UnityContainer();container.RegisterType<MyDbContext>(new InjectionConstructor("ConnectionStringName"));container.RegisterType<IAuthenticationManager>(   new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication));container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(   new InjectionConstructor(typeof(MyDbContext)));container.RegisterType<IRoleStore<IdentityRole, string>, RoleStore<IdentityRole>>(   new InjectionConstructor(typeof(MyDbContext)));container.RegisterType<IdentityFactoryOptions<ApplicationUserManager>>(new InjectionFactory(x =>   new IdentityFactoryOptions<ApplicationUserManager>   {      DataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("ApplicationName")   }));container.RegisterType<ApplicationSignInManager>();DependencyResolver.SetResolver(new UnityDependencyResolver(container));