StructureMap and ASP.NET MVC 3 – Getting Started

I have become a big fan of the principle of dependency inversion over the last couple years. My tool of choice is StructureMap though I use Unity at work. It actually matters little which you use if you choose to use an IoC library. Much more important is your understanding of the principle and using that to make your software better. But this post is not here to discuss the meanings of these terms; its point is simple: How do you hook up StructureMap to ASP.NET MVC 3’s new IoC hooks?

Good question. Unfortunately, it may not be as easy as you think. I have figured out most of it now though I still have some gaps to fill in. I am going to finish out this process by starting over and blogging my way through the setup process so everyone can see the error messages and know they aren’t alone. I’ll be posting the source code as I go along here up on Github. The goal is to create a small, reusable library so I don’t have to do this more than once. It is a bit more painful than I would like. I am sure others have done this (I have seen some sample code on the web) and I’m sure MVC Turbine will come out with support (I would expect nothing less of Javier) but this is for those who want to see how it all works.

Caveat: I am totally making this up as I go along. Finding good sources for how to do all this is not easy. Feel free to comment and critique as I would like to improve things.

In this first post we will get started. We’ll see a number of errors along the way, hopefully just because I’ve missed something obvious and not because of a deficiency in the way the feature was implemented.

Getting Started – IDependencyResolver

The core piece of the new IoC support in ASP.NET MVC 3 is the IDependencyResolver. You hook up an IoC container by implementing this interface on a class and supplying it with your container. In our sample code, I created a class called “StructureMapDependencyResolver”, which implements IDependencyResolver. We’ll discuss the “how” of that in a moment. First, the prep in the global.asax.

Your new yet-to-be-implemented StructureMapDependencyResolver would be setup in the global.asax through the static SetResolver method on DependencyResolver. You will also want to create a StructureMap container to pass in. In all my examples in this series I will manually setup all dependencies instead of doing some type scanning so all can follow along in the details. So this is what that would look like:


protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    IContainer container = new Container(x =>
    {
    });

    DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));
}

So now back to the implementation of StructureMapDependencyResolver. The interface being implemented has two methods, one for getting singly-registered services (GetService) and another for multiply-registered services (GetServices). The implementation would involve using StructureMap internally to return the types requested by both methods. As can be seen above, we pass that into the constructor and the implementation would look something like this:


public class StructureMapDependencyResolver : IDependencyResolver
{
    public StructureMapDependencyResolver(IContainer container)
    {
        _container = container;
    }

    private IContainer _container;

    public object GetService(Type serviceType)
    {
        object instance = _container.TryGetInstance(serviceType);
        return instance;
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _container.GetAllInstances(serviceType).Cast<object>();
    }
}

We will tweak that later.

Run the app and nothing seems to have changed. So far so good. I want to start by passing in a dependency into my constructor to see how that works out with what we have done. I create an interface and a class that implements it. I’ll have that class return some text from a string and output that to the page. Here is the simple implementation.


public class Bar : IBar
{
    public string IPityTheFoo()
    {
        return "Foo, I pity you!";
    }
}

public interface IBar
{
    string IPityTheFoo();
}

...and put this in the constructor for our HomeController...


public class HomeController : Controller
{
    public HomeController(IBar bar)
    {
        _bar = bar;
    }

    private IBar _bar;

    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC! " + _bar.IPityTheFoo();

        return View();
    }
}

Now if we run the site it explodes with the error “No parameterless constructor defined for this object.”.

No parameterless constructor defined

What I think that this is telling us is that we need a controller activator (it is the previous step in the stack trace, if you didn't notice).

Pimping Controllers – IControllerActivator

If you used IoC containers in ASP.NET MVC 1 and 2, you probably pimped out your controllers by creating a controller factory. That’s not how you do it in v3's ioc stuff (though you still can as nothing is stopping you). Instead, you create  a custom controller activator. Here is a basic implementation of a StructureMapControllerActivator.


public class StructureMapControllerActivator : IControllerActivator
{
    public StructureMapControllerActivator(IContainer container)
    {
        _container = container;
    }

    private IContainer _container;

    public IController Create(RequestContext requestContext, Type controllerType)
    {
        return _container.GetInstance(controllerType) as IController;
    }
}

Now we will hook that up in the global asax like so:


protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    IContainer container = new Container(x =>
    {
        x.For<IControllerActivator>().Use<StructureMapControllerActivator>();
    });

    DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));
}

Next we’ll run our app. Success!

No parameterless constructor defined

Okay, maybe not success. We get a message saying “The IControllerFactory 'System.Web.Mvc.DefaultControllerFactory' did not return a controller for the name 'Home'.” In other words, the controller activator is asking the IoC container for an instance of that controller, and the container doesn’t have it. One way we can solve this is by having the dependency resolver register the type if it is instantiatable. You would do that like so:


public object GetService(Type serviceType)
{
    object instance = _container.TryGetInstance(serviceType);

    if (instance == null && !serviceType.IsAbstract)
    {
        _container.Configure(c => c.AddType(serviceType, serviceType));
        instance = _container.TryGetInstance(serviceType);
    }

    return instance;
}

So first, when GetService is called, it asks the container for an object of that type. If it doesn’t find one and if that type isn’t abstract, it will then configure the container to start returning the type then ask for it again. Voila, auto registration of sorts. (I totally stole this idea from a post on Stack Overflow)

If we run the app again we will still get an error, but this is because we have not yet told our container how to map IBar to Bar.

No parameterless constructor defined

So let us do that. This is what our final global.asax would look like:


protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    IContainer container = new Container(x =>
    {
        x.For<IControllerActivator>().Use<StructureMapControllerActivator>();
        x.For<IBar>().Use<Bar>();
    });

    DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));
}

So that is step one. Most of the other integration point setups should go more smoothly. Of course the above seems at least relatively straightforward only because I've gone through this multiple times and made a lot more false starts (this has been frustrating). The above might be a false start as well though I can confirm that it definitely appears to work. But is there a simpler way?

Like I said before, I am kinda making this up and experimenting as I go. If you have suggestions, I'm open. I'll try to post on another extension point tomorrow. Stay tuned!

Comments

Gleb 2011-02-08 08:28:40

You're an idiot! Use IAssemblyScanner to decouple web app from actual implementation!!

Eric Sowell 2011-02-08 06:59:23

Ah yes, the ever so fun anonymous commentator with fake email address. It is actually against my better judgment to approve your comment but I will out of good humor.



So I have a quote for you from above: "You will also want to create a StructureMap container to pass in. In all my examples in this series I will manually setup all dependencies instead of doing some type scanning so all can follow along in the details." I normally do type scanning but, as I mention above, I am manually setting up all my dependencies so those following along can see, quite explicitly and clearly, exactly what is being setup with StructureMap. It is a pedagogical device.



But, heh, everyone needs to experience a little prickishness every once in a while. Feel free to keep commenting on my posts but I would prefer that you would at least have a little more humility next time since you critiqued, and insulted, this time without actually paying attention to what is going on.

Cheap Flowers 2011-02-11 08:30:34

There is no real need for the StructureMapControllerActivator. If you register your controllers with your IoC container, they will be resolved by your DependencyResolver automatically.

Eric Sowell 2011-02-11 08:48:41

Oh, but that is so old school :)

More seriously, if you are just injecting controllers, I agree. That works and it easier as well. That's how I did it in v1 and v2 and it worked fine for those. IDependencyResolver is v3's way of injecting dependencies into not only controllers but also filters, model binders, etc., so if you want to hook into that, IDependencyResolver is the way to go.



That being said, I'm not sold yet on the integration points. So far it has proven to be a pain to get various things up and running. But since I haven't worked through it all yet, I'm withholding my own judgment for the moment.

Kenny Nguyen 2011-02-14 01:29:41

What if I have like 10 different interfaces, IBar, IFoo, IService, IUser, etc.... Is there a way that I can hook up to all these interface without having to config it 10 times?

Thanks.

Eric Sowell 2011-02-14 11:23:33

Yes, there is a much easier way than manually configuring your dependencies. Take a look at StructureMap's type scanning api. That's what I normally use to automatically hook up most of my dependencies.

Charles Vallance 2011-03-05 03:53:49

I don't think you need to worry about the IControllerActivator implementation at all.

ASP.NET MVC 3 should automatically try and use the DependencyResolver registered in the Application_Start in conjunction with the default ControllerActivator to inject the controllers.

You're getting the "No parameterless constructor defined for this object." exception because your controller had a dependency on 'IBar' and at that stage you hadn't registered IBar with StructureMap so the default ControllerActivator tried to find a parameterless constructor.

Eric Sowell 2011-03-08 07:34:00

I just tried setting up IBar with the container and the error remains. From what I've gathered, just implementing IControllerActivator works for some IoC containers but not others. Depends on how they do object creation or something. I haven't dug in enough yet to know.

Charles Vallance 2011-03-09 12:16:28

Interesting. I too am using StructureMap and don't have to implement IControllerActivator... something must be different.

BUT in saying all I've said, I must admit that I'm tending towards implementing it because if you've forgotten to hook something up, the "No parameterless constructor defined for this object" error isn't very helpful.

curieuse 2011-04-04 01:13:21

Throughout this fascinating discussion, I'm shocked the code actually compiles. Am I the only one who doesn't see the definition the Container class?

Eric Sowell 2011-04-04 01:32:26

It's a StructureMap type so "using StructureMap" should do the trick. Perhaps I should update the code to make that clear.

Brett Zink 2011-08-26 11:07:00

This is excellent. Very nice tutorial. I'll be able to pick it up here and expand on it.

Thanks!

Nelson P. V. 2011-10-18 10:32:47

The below post clearly explains the reason for getting "No parameterless constructor defined for this object" error at the first place.

http://blogs.msdn.com/b/elee/archive/2010/11/19/asp-net-mvc-3-idependencyresolver-and-structuremap.aspx

Madhan 2011-10-20 07:59:19

Very nice article. Clean,neat and developer friendly :).

Gholamreza 2012-06-01 12:44:52

Thanks man
it is really helpful and informative blog
about how to apply structureMap in mvc 3.0 i found ever!!!