Integration with NInject components in MVC3 to implement dependency Injection Design

Source: Internet
Author: User

This is a topic in this MVC3 lecture.

Glossary

Dependency Injection: Dependency Injection. Sometimes it is also called reverse control (Ioc. Regardless of the term, it generally means that some external services on which our application depends can be dynamically injected as needed, rather than explicitly restrained in the application in advance. This idea should be meaningful in the current software development field to ensure the flexibility of the architecture.

The MVC Framework provides inherent support for the dependency Injection design. With some well-known DI components, such as NInject, we can easily implement the features mentioned above.

 

Scenario

Our applications need to support various data sources, and we hope that they can be easily switched in the future without changing the data source to make changes to the Contoller, Model, or View.

 

Full source code of this article, please download MvcApplicationDISample.rar here

 

Step 1: Prepare an MVC Project (select a blank template)

Step 2: Prepare a business entity type
using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace MvcApplicationDISample.Models{    public class Employee    {        public int ID { get; set; }        public string FirstName { get; set; }        public string LastName { get; set; }    }}

Step 3: Prepare a data access interface definition
using System;using System.Collections.Generic;using System.Linq;using System.Text;using MvcApplicationDISample.Models;namespace MvcApplicationDISample.Services{    public interface IDataService    {        Employee[] GetEmployee();    }}
Step 4: Create a HomeController

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using MvcApplicationDISample.Services;using MvcApplicationDISample.Models;namespace MvcApplicationDISample.Controllers{    public class HomeController : Controller    {        IDataService DataService;        public HomeController(IDataService service)        {            DataService = service;        }        //        // GET: /Home/        public ActionResult Index()        {            var data = DataService.GetEmployee();            return View(data);        }    }}

Note: You need to add a special constructor for HomeController to pass in the IDataService interface. Generally, all DI components are injected in this way.

When designing HomeController, we don't need to worry about which DataService will be used in the future. We just need to pass in the specific implementation of an IDataService, which is the essence of DI.

 

So far, the preparations we should do are basically ready. Let's take a look at how to integrate DI components to meet our needs.

 

Step 5: Introduce NInject Components

This is my favorite DI component. It also has a dedicated extension for MVC3

 

After adding this component, in addition to automatically adding many references, there is also a special file App_Start \ NinjectMVC3.cs

 

[assembly: WebActivator.PreApplicationStartMethod(typeof(MvcApplicationDISample.App_Start.NinjectMVC3), "Start")][assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(MvcApplicationDISample.App_Start.NinjectMVC3), "Stop")]namespace MvcApplicationDISample.App_Start{    using System.Reflection;    using Microsoft.Web.Infrastructure.DynamicModuleHelper;    using Ninject;    using Ninject.Web.Mvc;    public static class NinjectMVC3     {        private static readonly Bootstrapper bootstrapper = new Bootstrapper();        /// <summary>        /// Starts the application        /// </summary>        public static void Start()         {            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));            DynamicModuleUtility.RegisterModule(typeof(HttpApplicationInitializationModule));            bootstrapper.Initialize(CreateKernel);        }                /// <summary>        /// Stops the application.        /// </summary>        public static void Stop()        {            bootstrapper.ShutDown();        }                /// <summary>        /// Creates the kernel that will manage your application.        /// </summary>        /// <returns>The created kernel.</returns>        private static IKernel CreateKernel()        {            var kernel = new StandardKernel();            RegisterServices(kernel);            return kernel;        }        /// <summary>        /// Load your modules or register your services here!        /// </summary>        /// <param name="kernel">The kernel.</param>        private static void RegisterServices(IKernel kernel)        {        }            }}

This type is very interesting. The WebActivator. PreApplicationStartMethod method actually registers a method that runs before the MVC program starts. You should be able to understand the code. It adds a new Kernel (used as the injection container) in CreateKernel ).

 

Step 6: Create an IDataService implementation
using System;using System.Collections.Generic;using System.Linq;using System.Web;using MvcApplicationDISample.Models;namespace MvcApplicationDISample.Services{    public class SampleDataService:IDataService    {        #region IDataService Members        public Employee[] GetEmployee()        {            return new[]{                new Employee(){ID=1,FirstName="ares",LastName="chen"}};        }        #endregion    }}

For example, we use a hard-coded method to implement the service.

Step 7: Implement Injection

Return to the App_Start \ NinjectMVC3.cs file and modify RegisterServices as follows:

       /// <summary>        /// Load your modules or register your services here!        /// </summary>        /// <param name="kernel">The kernel.</param>        private static void RegisterServices(IKernel kernel)        {            kernel.Bind<Services.IDataService>().To<Services.SampleDataService>();        }      

Step 8: test the Controller function

We can see that the data has been displayed. This indicates that the Index method in HomeController indeed calls the SampleDataService we inserted later. However, you can see this point more clearly.

So far, we have implemented a simple dependency injection instance with the Ninject component. Ninject has such a special file for MVC 3, which greatly facilitates our programming. However, even if this file is not available, we can use other methods to meet the requirements.

The following describes two more traditional implementation methods by extending the MVC component.

First: Implement custom ControllerFactory

As we all know, Controller is actually generated by ControllerFactory. In order to automatically inject our services to all newly created controllers, we can use our brains from the ControllerFactory place.

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using Ninject;using MvcApplicationDISample.Services;namespace MvcApplicationDISample.Extensions{    public class InjectControllerFactory:DefaultControllerFactory    {        private IKernel kernel;        public InjectControllerFactory()        {            kernel = new StandardKernel();            kernel.Bind<IDataService>().To<SampleDataService>();        }        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)        {            return (IController)kernel.Get(controllerType);        }    }}

To use this custom ControllerFactory, we need to modify the Application_Start method in the Global. ascx file and add the following bold code

        protected void Application_Start()        {            AreaRegistration.RegisterAllAreas();            RegisterGlobalFilters(GlobalFilters.Filters);            RegisterRoutes(RouteTable.Routes);           ControllerBuilder.Current.SetControllerFactory(new Extensions.InjectControllerFactory());        }

 

After doing this, we can test the Index Action in HomeController and find that it still works normally.

 

 

Type 2: Implement custom DependencyResolver

As the name implies, This is the processor specifically used in the MVC Framework to process the so-called dependencies. It can be said that this is a backdoor specially prepared by MVC for DI. Below is an example I wrote

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using Ninject;using MvcApplicationDISample.Services;namespace MvcApplicationDISample.Extensions{    public class InjectDependencyResolver:IDependencyResolver    {        private IKernel kernel;        public InjectDependencyResolver()        {            kernel = new StandardKernel();            kernel.Bind<IDataService>().To<SampleDataService>();        }        #region IDependencyResolver Members        public object GetService(Type serviceType)        {            return kernel.TryGet(serviceType);        }        public IEnumerable<object> GetServices(Type serviceType)        {            return kernel.GetAll(serviceType);        }        #endregion    }}
 

So how can we use this custom processor?

Very simple. We are still modifying the Application_Start method in the Global. asax file.

        protected void Application_Start()        {            AreaRegistration.RegisterAllAreas();            RegisterGlobalFilters(GlobalFilters.Filters);            RegisterRoutes(RouteTable.Routes);            //ControllerBuilder.Current.SetControllerFactory(new Extensions.InjectControllerFactory());            DependencyResolver.SetResolver(new Extensions.InjectDependencyResolver());        }

Note that the previous code for setting ControllerFactory can be commented out.

The final effect of this solution is the same as before.

 

 

Full source code of this article, please download MvcApplicationDISample.rar here

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.