Example VS 2015 Solution [ link ] for this article
StructureMap (SM) is one of the most popular IoC tools for MVC out there. But, one of the biggest issues for first timers is the web has tons of post on it and often they are not clear on the version and etc…
For this Article I am using:
- .Net 4.5.2
- MVC 5
- StructureMap 3.1.1.134
- StructureMap MVC5
Official documentation: http://structuremap.github.io/
As you may already know, the MVC default controller factory defaults to parameterless constructors. When you change a Controller it accept a parameter, the .net mvc compiler will complain about it. Often you will see an error that reads: No parameterless constructor define for this object. To solve this issue you will need to implement your own ControllerFactory and get it to pass request for controllers through structuremap (SM) or you can use the SM MVC 5 Nuget package in Visual Studio (later in this article). SM, will then inspect each request and attempt to resolve those dependencies with a concrete implementation.
A mvc controller class with a parameter based constructor as the default.
public class ContactController : Controller { private readonly IContactRepository iRepository; public ContactController(IContactRepository repository) { iRepository = repository; } public ActionResult Index() { return View(iRepository.GetContacts()); } }
In the above code you will see I have a constructor that is expecting some kind of repository for contacts. So as I was saying above, you will need to create a Default Controller Factory. This grunt work can be avoided if you use any of the nuget packages for MVC and Structure Map. But for if you want to do it manually you will need to wire things up yourself.
A bit more succinctly, since MVC framework has its own default implementation of the IControllerFactory interface which is DefalutControllerFactory and since it is not a sealed class so you can extend it. So you override the virtual method GetControllerInstance and change the implementation to whatever we need and then register this in the global.asax.cs file start up. (I suggest you not do this…)
Instead, you can make this much easier by leveraging a nuget package to do most of the grunt work for you.
An example of implementing the DefaultControllerFactory:
using System; using System.Web.Mvc; using StructureMap; namespace ContactManager.IoC { public class DependencyControllerFactory : DefaultControllerFactory { protected override IController GetControllerInstance(Type controllerType) { return ObjectFactory.GetInstance(controllerType) as Controller; } } }
Leveraging your IDE’s tools…
In visual studio 2015 I created a simple mvc application. See this [ link ] for the code accompanying this blog post…
Then I went into Nuget and added StructureMap MVC5. ( https://www.nuget.org/packages/StructureMap.MVC5/ )
What caught me off guard initially was that I did not see any code in the application_start method referencing the StructureMap Dependency resolver or such. After digging about I figured out it was using an assembly trick to wire up SM before the application start. See this link for a quick explanation of PreApplicationStartMethod.
In App_Start folder you will see a file called StructuremapMvc.cs. Open it and look for these two entries..
[assembly: PreApplicationStartMethod(typeof(StructuremapMvc), “Start”)]
[assembly: ApplicationShutdownMethod(typeof(StructuremapMvc), “End”)]
This is what wires up your mappings of concrete implementations of interfaces located in the DefaultRegistry.cs file in the DependencyResolution folder in your solution.
So all you have to do now is update the DefaultRegistry.cs file with you specific needs using the For<>.Use<>(); syntax.
Code-ON…
A few misc reads and link:
Look here for more details on the mvc 5 nuget package for MVC https://github.com/webadvanced/Structuremap.MVC5
For specific integratinos: http://structuremap.github.io/integrations/
General Nuget package: https://www.nuget.org/packages/structuremap/
Structuremap and entity framework can be a bitch, read this:
Entity Framework – The best example is this blog post from Jimmy Bogard.
So some quick unstructured notes…