JAX
JAX

Reputation: 1620

Dependency Injection in ASP.NET MVC

I've been using Dependency Injection in ASP.NET MVC the way I've explained in the below code, but I'm not sure if that is the right and standard way to do it. So I just wanna know if what I'm doing is wrong or if there is a better and more professional way to do it.

public interface IService {
    public Boolean AddRecord(Object _Model);
}

public class Employee: IService {
    DataBase Context = new DataBase();
    public Boolean AddRecord(Object _Model) {
        Context.Add((EmployeeModel) _Model);
        return Context.SaveChanges() != 0;
    }
}

public class DataController: Controller {
   IService service;
   public DataController(IService service) {
       this.service = service;
   }

   public ActionResult AddRecord(Object _Model, String Caller) {
        if (service.Add(_Model)) {
            TempData["Result"] = "Data Added";
            return RedirectToAction(Caller);
        }
        TempData["Result"] = "Please try again";
        return View (Caller, _Model);
   } 
}

When I wanna use the controller with the DI, I do: (Is this the right way to consume the DataController)

public class TestController: Controller {
      public ActionResult Index () {
          return View();
      }

      public ActionResult TestIt (EmployeeModel _Model) {
          DataController DC = new DataController(new Employee());
          return DC.AddRecord(_Model, "../Test/TestIt");
      }
}

Upvotes: 1

Views: 1918

Answers (1)

Simon Whitehead
Simon Whitehead

Reputation: 65097

You have the general concept of Dependency Injection / Inversion down. That is, you've understood that instead of this:

public class Example {
    public void SomeFunc() {
        var service = new Service();
        service.DoStuff();
    }
}

..you do this:

public class Example {
    private readonly IService _service;

    public Example(IService service) {
        _service = service;
    }

    public void SomeFunc() {
        _service.DoStuff();
    }
}

.. and you supply the dependency manually via the calling code.. such as a Controller:

public HomeController : Controller {
    [HttpGet]
    public ActionResult Index() {
        var example = new Example(new Service());
        example.SomeFunc();
        // .. the rest ..
    }
}

So, the first part is Dependency Inversion. You have inverted the dependency chain from being top down to bottom up. The second part (the above code block) is Dependency Injection.

Notice in the above block of code that the Controller has no dependencies injected. This is where Inversion of Control comes in.

Inversion of Control is a pattern where code completely external to the currently running code decides how it functions. In this context, it means some external code - somewhere else - decides how to supply dependencies to your controller.

(Note, I am quite familiar with Ninject - so the below examples are using Ninject. There are plenty of other available DI/IoC containers available)

Ninject is a framework that can help with this (and many others). Ninject has an extension for ASP.NET MVC which automatically builds and supplies controller instances for you - plus your dependencies.

Without providing a full tutorial on using Ninject (which I will leave as an exercise to the OP to Google), the basics of it is this.

You declare a "module" with the configuration for your dependencies. Using the above examples, your module might look like this:

public class YourModule : NinjectModule {
    public override void Load() {
        Bind<IExample>().To<Example>().InRequestScope();
        Bind<IService>().To<Service>().InRequestScope();
    }
}

This will wire up all requests for an IExample to an Example, and IService to an instance of a Service. So your Controller would become:

public class HomeController : Controller {
    private readonly IExample _example;

    public HomeController(IExample example) {
        _example = example;
    }

    [HttpGet]
    public ActionResult Index() {
        _example.SomeFunc();
        // .. the rest ..
    }
}

The container (in this case, Ninject) looks at your external code (the YourModule class) and determines what IExample should be. It sees that you've said it should be an instance of an Example class. Example also requires a dependency of type IService. So Ninject will again look at YourModule and determines that it should be an instance of Service. It continues to go down the object hierarchy until it completes the construction of the objects.

Hopefully that makes sense - it is definitely hard to explain these concepts in text.

I haven't viewed this video (I am running off of really really terrible WiFi hotspot while I wait for an internet connection!) so I can't verify it's quality, but a quick Google search turned this up for setting up Ninject and MVC: http://www.youtube.com/watch?v=w_MehI2qBTo

You would definitely benefit from Googling around some Inversion of Control and/or Ninject videos to understand what frameworks like it are for.

It is important to note too that frameworks like Ninject can also control scope. In the example above, I used InRequestScope against the bindings. This means that Ninject will instantiate the dependency at the start of the web request - and dispose of it afterward. This removes the need for you to worry about that.

Upvotes: 1

Related Questions