I routinely get questions about using an IoC container, like StructureMap, with ASP.NET Identity, particularly with the way it’s set up in the default ASP.NET MVC project template.  In this post, I’ll show you the quickest way to IoC-enable the starter app.

[more]

First, fair warning: the default MVC app template is rough.  I would not use it as a starting point for a real app, ever.  I’ll elaborate more on why in the future, perhaps.  But for now, let’s say you decided to use the starter template anyway, but you want to apply some actual good design principles to it.  The AccountController looks like this:

    public class AccountController : Controller
    {
        private ApplicationSignInManager _signInManager;
        private ApplicationUserManager _userManager;

        public AccountController()
        {
        }

        public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager )
        {
            UserManager = userManager;
            SignInManager = signInManager;
        }

        public ApplicationSignInManager SignInManager
        {
            get
            {
                return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
            }
            private set 
            { 
                _signInManager = value; 
            }
        }

        public ApplicationUserManager UserManager
        {
            get
            {
                return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
            }
            private set
            {
                _userManager = value;
            }
        }
    ...
    }

*shudder*

Gross.  Anyway.

Let’s assume we’re not going to use the funky OWIN service location junk, and we’re instead going to let our IoC container do its magic.

Pro-tip: if you want IoC in your MVC app quickly, feel free to install the Heroic.Web.IoC NuGet package.

So, we can pretty quickly hack this controller to be a little more IoC friendly:

    public class AccountController : Controller
    {
        private ApplicationSignInManager _signInManager;
        private ApplicationUserManager _userManager;

        //Don't need it!
        //public AccountController()
        //{
        //}

        public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager )
        {
            UserManager = userManager;
            SignInManager = signInManager;
        }


        public ApplicationSignInManager SignInManager
        {
            get
            {
                return _signInManager; //?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
            }
            private set 
            { 
                _signInManager = value; 
            }
        }

        public ApplicationUserManager UserManager
        {
            get
            {
                return _userManager; // ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
            }
            private set
            {
                _userManager = value;
            }
        }
    ...
    }

(Yes, I said hack, not refactor.  The only refactoring that will work on code like this is FIRE.)

Great!  Now let’s run our app, and….

image

Yeah, you knew it wasn’t going to be that easy! 

Fortunately Jeremy Miller has taken pity on us, and StructureMap tells us exactly what’s wrong.  It’s trying to build up an ApplicationUserManager to inject into our controller, but it doesn’t know what to use for IUserStore<ApplicationUser>.  That’s an interface, not a concrete type, so StructureMap needs us to tell it what type we’d like it to use.

If you’re using Heroic.Web.IoC, you can pop open the StructureMapConfig class.  If you’re using something else, that’s fine, just open up your default registry, config block, or wherever you want to configure the container, and drop in the following code:

cfg.For<ApplicationSignInManager>().Use(ctx =>
    ctx.GetInstance<HttpContextBase>().GetOwinContext().Get<ApplicationSignInManager>());
cfg.For<ApplicationUserManager>().Use(ctx =>
    ctx.GetInstance<HttpContextBase>().GetOwinContext().GetUserManager<ApplicationUserManager>());

Wait!  You just wrapped the OWIN context mess into your StructureMap config!”

Indeed I did!  Did I mention that the starter template is rough?  Rough probably isn’t strong enough…. It’s spaghetti calling ramen noodles crossbred with a pufferfish.  Cleaning that up is a lot more than we can do in one blog post.  BUT, the above config code will at least start you on the path to being able to leverage IoC:

image

If there’s enough interest in the topic, I may continue on with this train of thought and show you how to *properly* refactor this into something that is cleaner.  If you’d like to see that, sound off in the comments!  Oh, and if you want to check out the sample app, it’s on Github!