This post is to show how to implement Dependency Injection in ASP.NET MVC 3 application with simple steps. For Details on Dependency Injection (DI) please refer to my article here.
For the sake of simplicity and to understand the idea, I have simply specified all the classes in same project(web application here). In real time scenario this might extend to multiple class libraries based on the nature of the project.
In our example, we're targeting a Mark sheet creation with minimal and predefined data. MarkSheetController expects a MarksheetModel and the MarkSheetModel expects a MarkEvaluator which we're going to achieve with Constructor injection as follows.
Implementaiton Details
First we need to install the Ninject.MVC3 Nuget package using Nuget manager. For details on Nuget manager please verify my post here. Upon installing the package, a file called NinjectWebCommon.cs will get created under the folder called App_Start. In the static method called RegisterServices, add the statement to register the dependencies with Ninject container. Following Snippets are self explanatory to understand the concept.
Snippet 1: (App_Start/NinjectWebCommon.cs => NinjectWebCommon.RegisterServices())
private static void RegisterServices(IKernel kernel) { kernel.Bind<IMarkSheetModel>().To<MarkSheetModel>(); kernel.Bind<IMarkEvaluator>().To<MarkEvaluator>(); }
In the above snippet I've registered with Ninject that MarkSheetModel concrete class is bound to IMarkSheetModel and MarkEvaluator concrete class is bound to IMarkEvaluator interface. Based on this Ninject resolves the dependency by creating instance for the respective concrete class and pass it in the place of the related interface specification. Following snippet shows how we're making use of constructor injection to achieve that.
Snippet 2: (MarkSheetController - note the IMarkSheetModel parameter in the constructor)
public class MarkSheetController : Controller { private IMarkSheetModel model; public MarkSheetController(IMarkSheetModel modelParam) { model = modelParam; } // // GET: /MarkSheet/ public ActionResult Index() { model.LoadDetails(); return View(model); } }
Snippet 3: (MarkSheetController - note the IMarkEvaluator parameter in the constructor)
public class MarkSheetModel : IMarkSheetModel { private IMarkEvaluator evaluator; public string StudentId { get; set; } public string StudentName { get; set; } public IEnumerable<Subject> SubjectList { get; set; } public int Total { get; private set; } public decimal Average { get; private set; } public string Grade { get; private set; } public MarkSheetModel(IMarkEvaluator evaluatorParam) { evaluator = evaluatorParam; } public void LoadDetails() { this.StudentId = "S1001"; this.StudentName = "Sample"; this.SubjectList = new List<Subject> { new Subject{ SubjectId="Sub0001", SubjectName ="Sub 1", Score = 78}, new Subject{ SubjectId="Sub0002", SubjectName ="Sub 2", Score = 84}, new Subject{ SubjectId="Sub0003", SubjectName ="Sub 3", Score = 72}, new Subject{ SubjectId="Sub0004", SubjectName ="Sub 4", Score = 69}}; this.Total = this.evaluator.CalculateTotal(this.SubjectList); this.Average = this.evaluator.CalculateAverage(this.SubjectList); this.Grade = this.evaluator.CalculateGrade(this.SubjectList); } } public interface IMarkSheetModel { void LoadDetails(); IEnumerable<Subject> SubjectList { get; set; } string StudentId { get; set; } string StudentName { get; set; } } public class Subject { public string SubjectId { get; set; } public string SubjectName { get; set; } public int Score { get; set; } }
Snippet 4:
public class MarkEvaluator : IMarkEvaluator { public int CalculateTotal(IEnumerable<Subject> subjectList) { return subjectList.Sum(su => su.Score); } public decimal CalculateAverage(IEnumerable<Subject> subjectList) { return Convert.ToDecimal(CalculateTotal(subjectList)) / subjectList.Count(); } public String CalculateGrade(IEnumerable<Subject> subjectList) { decimal averageScore = CalculateAverage(subjectList); if (averageScore > 80) { return "Grade A"; } else if (averageScore > 70) { return "Grade B"; } else if (averageScore > 60) { return "Grade C"; } else { return "Grade D"; } } } public interface IMarkEvaluator { decimal CalculateAverage(IEnumerable<Subject> subjectList); string CalculateGrade(IEnumerable<Subject> subjectList); int CalculateTotal(IEnumerable<Subject> subjectList); }
While executing the above snippets, the constructor of the MarkSheetController and MarkSheetModel is supplied with the respective instance.
References:
https://github.com/ninject/ninject.web.mvc/wiki/MVC3
Error 1 The type 'MvcApplication1.Models.MarkEvaluator' cannot be used as type parameter 'TImplementation' in the generic type or method 'Ninject.Syntax.IBindingToSyntax.To()'. There is no implicit reference conversion from 'MvcApplication1.Models.MarkEvaluator' to 'MvcApplication1.Models.IMarkEvaluator'. D:\Aplicatii\IOC\MvcApplication1\MvcApplication1\App_Start\NinjectMVC3.cs 15 13 MvcApplication1
ReplyDeleteGreat Article
ReplyDeleteMund offered an instance from CNC Software’s machine shop, where a few of the the} software individuals have been working on a complex aerospace part for certainly one of their prospects. At the same time, additionally they needed to strive new toolpaths from the event department. Rather than generate the whole program at once, they programmed every section individually, “taking aside the watch” to grasp how it it} worked. hp stylus pen It was solely after they were snug with the results that they moved on to the rest of|the remainder of} the part.
ReplyDelete