Day 3 – Dot NET on Linux – Dependency Injection with Ninject

Intro

Dependency injection along with Moc Frameworks are becoming  increasingly popular. They allow decoupling of parts of the system to allow them to be substituted easily during runtime. This is especially powerful when the item being substituted is an expensive entity which is hard to consume during unit testing.

The Source Code

This post is part of my Dot Net On Linux posts. All the source the source code from the series of posts is available on GitHub here

What is Dependency Injection?

DI for short is a control mechanism which allows us to satisfy the Dependency Inversion Principle of the SOLID Design Principles.

By dictating to lower level components what other lower level components are to be used we can uncouple parts of a system to allow them to be independently replaced. This is done by injecting concrete class implementations into classes which are expecting abstractions.

DI is the principle which also allows us to inject mock implementation of components which are expensive or hard to consume while unit testing. This can allow us to unit test without a database or 3rd party web services. This can allow a greater coverage of unit testing and also allowing unit testing to be run quicker meaning there is more chance they will be run.

Ninject

Ninject is a DI framework which is commonly used. What it lacks comparing to other DI frameworks it makes up in its simplicity.

The Source Code

All the source code from the series of posts is available on GitHub here.

Installation

wget http://ninject2.googlecode.com/files/Ninject-3.0.0.15-release-mono-2.0.zip
mkdir Ninject
mv Ninject-3.0.0.15-release-mono-2.0.zip Ninject
cd Ninject
unzip Ninject-3.0.0.15-release-mono-2.0.zip

Adding Ninject References

To add Ninject into a  project; highlight the project within the solution tree then from the Project menu “Project –> Edit References”.

From the “Edit References” dialog box select the .Net Assembly tab. Navigate to the unzipped Ninject directory and highlight Ninject.dll. Select the add button and then ok.

Ninject can then be imported into a class with “using Ninject”

The code

The most common occurrence of DI injection are

  • Resolve concrete class from abstract interface
  • Resolve concrete class with dependence of constructor DI
  • Resolve concrete class from abstract interface with configured constructor arguments
  • Conditionally resolve concrete class from abstract interface when injected into a child class

Resolve concrete class from abstract interface

The most common form of injection requires resolving a concrete implementation of a class when referencing its interface abstraction.
At an initial point in our application run time we create an instance of the DI kernel and register our required concrete class against our interface. Later on when we want to use the class via its abstraction we ask the DI kernel to resolve this from its abstract interface and provide us with an instance.


// The DI Kernel
var kernelInstance = new StandardKernel ();

// Bind our concre
kernelInstance.Bind().To (typeof(SimpleClass));

// Retrieval of a concrete implementation of our interface
var myClass = kernel.Get();

Resolve concrete class with dependence of constructor DI

If any constructor or class being resolved requires arguments these can be automatically passed in upon creation. As long as we have a parameterless constructor for the argument all this can happen automatically.


// Constructor of class being resolved by the DI kernel
public ClassWithDependancy (ISimpleClass simpleClass)
{
    this.SimpleClass = simpleClass;
}

// The DI Kernel
var kernelInstance = new StandardKernel ();

// Bind our concrete classes to abstractions
kernelInstance.Bind().To (typeof(SimpleClass));
kernelInstance.Bind().To (typeof(ClassWithDependancy));

// Retrieval of a concrete implementation of our interface
var myClass = kernel.Get();

Resolve concrete class from abstract interface with configured constructor arguments

An injection with parameters in the constructor is also catered for.

kernel.Bind().To (typeof(ClassWithConstructorParameters)).
WithConstructorArgument ("messageOne", "Hello").
WithConstructorArgument ("messageTwo", "There");

Conditionally resolve concrete class from abstract interface when injected into a child class

If two classes implement the same interface we can conditional config which is injected into an implementing classes constructor.

kernel.Bind().To().WhenInjectedInto();
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s