Introduction
In this article, we will learn how we can implement StructureMap IOC container / dependency injection in ASP.NET MVC 5. Actually, we have different tools able to ensure inversion of control pattern, like (Unity, Autofac, Ninject, StructureMap, etc…). In this demo, we will see the steps that should be used to perform StructureMap in ASP.NET MVC 5 application.
In this article, we are going to,
- Create MVC application.
- Configuring StructureMap IOC.
- Create repository.
- Create controller.
Create your MVC application
Open Visual Studio and select File >> New Project.
The "New Project" window will pop up. Select ASP.NET Web Application (.NET Framework), name your project, and click OK.
Next, new dialog will pop up for selecting the template. We are going choose MVC template and click OK button.
Configuring StructureMap IOC
After creating our project, we are going to add StructureMap IOC. For this, right click on References > Manage NuGet Packages, type StrucutreMap.MVC5 in search box, then click on Install button, as shown below.
You can also get StructureMap by using package manager console and run the following command:
PM> install-package StructureMap.MVC5
After installing StructureMap, from solution explorer we can notice that Dependency Resolution folder has been added, also StructuremapMVC.cs file in App_Start folder.
The important file which is needed is the DefaultRegistry.cs.
DefaultRegistry.cs
- namespace StructureMapMVC5.DependencyResolution {
- using Repository;
- using StructureMap.Configuration.DSL;
- using StructureMap.Graph;
-
- public class DefaultRegistry : Registry {
- #region Constructors and Destructors
-
- public DefaultRegistry() {
- Scan(
- scan => {
- scan.TheCallingAssembly();
- scan.WithDefaultConventions();
- scan.With(new ControllerConvention());
- });
- For<ICustomerRepository>().Use<CustomerRepository>();
-
- }
-
- #endregion
- }
- }
In Default Registry class, we are going configure StructureMap container. In fact, we have two way to configure our container - by using explicit registrations or conventional auto registration.
As you can see, in this example we are composing our application object by connecting abstraction (in this case ICustomerRepository) to concrete type (represented by CustomerRepository). To do that, we are using the fluent Api For<ICustomerRepository>().Use<CustomerRepository>() which registers a default instance for a given type.
If you also have more repetitive similar registrations, such registrations are painful. StructureMap provides auto registration and conversion mechanism which is able to register types automatically. This means, the scanner will register the default instance. Whenever you add an additional interface such IEmployeeRepository and a class EmployeeRepository, it’s automatically picked up by the scanner scan.WithDefaultConventions();
Create Repository
ICustomerRepository.cs
- using StructureMapMVC5.Models;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace StructureMapMVC5.Repository
- {
- public interface ICustomerRepository
- {
- IEnumerable<Customer> GetCustomers();
- }
- }
CustomerRepository.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using StructureMapMVC5.Models;
-
- namespace StructureMapMVC5.Repository
- {
- public class CustomerRepository : ICustomerRepository
- {
- public IEnumerable<Customer> GetCustomers()
- {
- var customerData = new List<Customer>()
- {
- new Customer() { ID = 1, Name = "Ali", Email = "[email protected]", Country = "Morocco"},
- new Customer() { ID = 2, Name = "Amine", Email = "[email protected]", Country = "Morocco"},
- new Customer() { ID = 3, Name = "Kumar", Email = "[email protected]", Country = "India"},
- new Customer() { ID = 4, Name = "Messi", Email = "[email protected]", Country = "Spain"},
- };
-
- return customerData;
- }
- }
- }
Create a controller
Now, we are going to create a controller. Right click on the controllers folder > Add > Controller> selecting MVC5 Controller – Empty > click Add.
Enter Controller name (‘CustomerController’).
CustomerController.cs
- using StructureMapMVC5.Models;
- using StructureMapMVC5.Repository;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
-
- namespace StructureMapMVC5.Controllers
- {
- public class CustomerController : Controller
- {
- private readonly ICustomerRepository _customerRepository;
-
- public CustomerController(ICustomerRepository customerRepository)
- {
- _customerRepository = customerRepository;
- }
-
-
- public ActionResult Index()
- {
- var customers = _customerRepository.GetCustomers();
-
- return View(customers);
- }
- }
- }
As you can see, I am creating Index() action that returns customers list from GetCustomers() method.
Adding View
It’s easy to do. Just right click on Index() action, select Add View and dialog will pop up; write a name for your View and finally, click Add.
- @model IEnumerable<StructureMapMVC5.Models.Customer>
-
- @{
- ViewBag.Title = "Index";
- }
-
- <h2>Index</h2>
-
- <p>
- @Html.ActionLink("Create New", "Create")
- </p>
- <table class="table">
- <tr>
- <th>
- @Html.DisplayNameFor(model => model.Name)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.Email)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.Country)
- </th>
- <th></th>
- </tr>
-
- @foreach (var item in Model) {
- <tr>
- <td>
- @Html.DisplayFor(modelItem => item.Name)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.Email)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.Country)
- </td>
- <td>
- @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
- @Html.ActionLink("Details", "Details", new { id=item.ID }) |
- @Html.ActionLink("Delete", "Delete", new { id=item.ID })
- </td>
- </tr>
- }
-
- </table>
Output
Now, you can run your application. Let’s see the output.