Monday, 7 November 2011

Explanation of Ninject Bindings and where we used them in our MVC Website (Part 1 - MVC Website)


Im going to summarize what we have done with our Ninject bindings and injection which allows us to follow the "Inversion of Control (IOC Container)" principle in a project we are working on. 

As mentioned we are using Ninject as our IOC container:

The project architecture looks much like the following diagram:

Architecture Diagram

I will work my way from the top to the bottom of the architecture. Starting with the MVC web site all the way through to the Microsoft Crm layer.(This post  (Part 1 - MVC Website) just refers to the web site.)

One of the 2 BIG reasons we are using an IOC container (Ninject) is to allow us to separate all our layers (separation of concerns) so that they are Unit testable and also so that we can swap components out at a later date. We may want to replace our Crm later with a Sql server layer, doubtful but we are catering for this anyway as you never know what will be a requirement in the future. As long as our Sql server repository layer implements the same interface as our existing Crm repository layer, we can more or less swap out the Crm Repository with a new Sql Repository.

Mvc Website:
On the website layer we will be using Ninject to inject the following:
  • A GatewayAgent layer into our controller - the GatewayAgent layer separates the concerns of the controller from the concerns of our WCF SOA layer. 
  • An AutoMapper implimentation into our GatewayAgent - the mapper will map our presentation entities to our Domain entities.
  • Our presentation entity validation classes into our presentation entities - as we are using Fluent validation, we may want to ditch this later and inject a different type of validation.
The following diagram show part of the web site's global.asax file. This code uses Ninject to inject the above 3 items.

The Ninject Binding in the Global.asax class
Obviously, the web site has a reference to the Ninject.dll.

Most of this is set in stone for our site but one thing to note. As more development is done we will need to add more validators as we add more presentation entities to our site. So when we add an Invoice presentation entity to the site a related Invoice Validator class will need to be added to the ConfigureKernel method, shown above, in our global.asax file.

Note: the line:
- kernel.Bind<IValidator<Contact>>().To<ContactValidator>(); 
means, when we call validate on a Contact presentation entity, 
we would like to use the ContactValidator class to carry out the validation

Sample Contact Validator
You can see in the ConfigureKernel method above that we also inject a ContactGateway.
The following line shows this:

This means that when we refer to IContactGateway we would like to use the concrete class ContactGateway.
So in our controller we see the following code:
Sample controller

Why is this good? Because you can then mock up a ContactGateway in a unit test to test your controller.

A unit test for the controller
As mentioned above, we also inject a mapper implementation into our web site:
This is used to map our domain entities to our presentation entities on the way up and our  presentation entities to our domain entities on the way down.

Why is this good? We may way to use a different mapping tool other than AutoMapper in the future. Injection will enable us to swap AutoMapper out for a different mapper tool.

This is the end of Part 1 - Explanation of Ninject Bindings and where we used them in our MVC Website

I will do another couple of posts on the other layers mentioned in the architecture diagram at the start of this post.