Have you ever heard about the term Inversion of Control (IoC) or dependency injection but you dont know exactly what it is or why you need it then continue reading. If you have never heard about it before and you are a developer then keep on reading also! Its a really cool way of programming (design pattern) and it can help you a lot in the future and its not that difficult 😉
First of all you might have heard about terms like Dependency Injection en Inversion of Control interchangeably. But there is a difference. DI is a design pattern but IoC is a mechanisme, or framework to automatically insert dependencies. Castle Windsor is for example an IoC.
Ok so what is Dependency Injection exactly. Let me give you a simple explanation:
When you go and get things out of the refrigerator for yourself, you can cause problems. You might leave the door open, you might get something Mommy or Daddy doesn’t want you to have. You might even be looking for something we don’t even have or which has expired.What you should be doing is stating a need, “I need something to drink with lunch,” and then we will make sure you have something when you sit down to eat. – John Munsch
And the main idea of an IoC framework is that if you want something you dont want to be bothered by all its dependencies. So it resolves it for you. But lets start with the design pattern.
Ok lets clarify this with a coding example. Lets say you are a person that can drive a vehicle. In that case we have a class like this:
1 2 3 4 5 6 7 8 |
public class Person { private Car myCar = new Car(); public void Drive() { this.myCar.drive(); } } |
The object Person depends on the object Car. This could be an issue if you want the person to drive a bus. You can solve this by updating the code like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class Person { private IVehicle vehicle {get; set;} public Person(IVehicle Vehicle) { this.vehicle = Vehicle } public void Drive() { this.vehicle.drive(); } } |
Now you inject the dependency when initializing the object Person. As long as the object Bus implements the interface IVehicle this person can drive it. Implementing a dependency like this is called the Dependency Injection design pattern.
But this pattern still has some issues. You have to initialize a Vehicle before you can create a new Person. But the vehicle can depend again on another dependency B which can depend on another dependency C. So before you can create a person you have to initialize object C, then initialize B and insert C then initialize a vehicle and insert B and then you can initialize a Person by inserting a vehicle object. Can you see the issue with this?
One way to solve this is using the Factory design pattern. With this pattern you create a static factory class that resolves all dependencies. So if you need a new Person all you do is:
1 |
Person Rowan = Person.Factory(); |
Factory is a static method that could look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class Person { private IVehicle vehicle {get; set;} public static Person Factory() { var C = new C(); var B = new B(C); IVehicle Bus = new Bus(B); return new Person(Bus); } public Person(IVehicle Vehicle) { this.vehicle = Vehicle } public void Drive() { this.vehicle.drive(); } } |
But now imagine that object B is changed and no longer depends on C but on an object D. That causes problems here because the factory method no longer works. You have to remember to update the factory method of object Person.
You can solve this by creating a factory method for every object. Your person factory method would look then like this:
1 2 3 4 5 |
public static Person Factory() { IVehicle Bus = Bus.Factory(); return new Person(Bus); } |
The Bus Factory method will call the B Object Factory method etc. But creating all these factory methods and maintaining them can also be an issue or something that you dont want to be bothered with. In that case it could be a good idea to use a IoC framework like Castle Windsor that does all the work for you.
Castle Windsor
Inversion of Control (called IoC) frameworks are different from all other kinds of frameworks in that you don’t see many calls to the framework in your code. In fact – in most applications (regardless of their size and complexity) you will only call the container directly in three places. That’s the most common pattern of usage and Windsor supports it fully.
Before I continue understand that there is a difference between Inversion of Control and a Inversion of Control Container.
Inversion of Control
Inversion of Control is a principle used by frameworks as a way to allow developers to extend the framework or create applications using it. The basic idea is that the framework is aware of the programmer’s objects and makes invocations on them.
This is the opposite of using an API, where the developer’s code makes the invocations to the API code. Hence, frameworks invert the control: it is not the developer code that is in charge, instead the framework makes the calls based on some stimulus.
You have probably been in situations where you have developed under the light of this principle, even though you were not aware of it.
Inversion of Control Container
An Inversion of Control Container uses the principle stated above to (in a nutshell) manage classes. That is, their creation, destruction, lifetime, configuration, and dependencies. This way classes do not need to obtain and configure the classes they depend on. This dramatically reduces coupling in a system and, as a consequence, simplifies reuse and testability.
There is some confusion created by people that think that ‘Inversion of Control’ is a synonym for ‘Inversion of Control Container’. As stated, Inversion of control is a broader principle.
Example using Castle Windsor
Start with creating a new empty project and add a reference to Castle Windsor using the NuGet package manager.
For this example I am using a simple Console Application. But Castle Windsor can be used in any C# application. I start with an empty application:
1 2 3 4 5 6 7 |
class Program { static void Main(string[] args) { ... } } |
Furthermore I created a component with some dependencies:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
public class Rowan { private IDependency1 object1; private IDependency2 object2; public Rowan(IDependency1 dependency1, IDependency2 dependency2) { object1 = dependency1; object2 = dependency2; } public void DoSomething() { object1.SomeObject = "Hello World"; object2.SomeOtherObject = "Hello Mars"; Console.WriteLine(String.Format("{0}\n{1}",object1.SomeObject,object2.SomeOtherObject)); } } public interface IDependency1 { object SomeObject { get; set; } } public interface IDependency2 { object SomeOtherObject { get; set; } } public class Dependency1 : IDependency1 { public object SomeObject { get; set; } } public class Dependency2 : IDependency2 { public object SomeOtherObject { get; set; } } |
What I like to do now is create a new instance of the component Rowan with the help of Castle Windsor.
- First create a Castle Windsor container. The preferred location for initiating Castle Windsor is in the entry project. Meaning put it in case of an MVC project in global.asax.cs (Application_Start) and in case of an application in your Program.Main.
1IWindsorContainer container = new WindsorContainer(); - Now add an installer. Castle Windsor can automatically find installers in your project when the installer implements the IWindsorInstaller interface. If you want Castle Windsor to run all installers in your assembly use:
1containerc .Install(FromAssembly.This()); - Somewhere in your application define a installer. An installer registers classes with Castle Windsor so that Windsor can resolve them later. An example of an installer:
1234567public class FooWindsorInstaller : IWindsorInstaller{public void Install(IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store){container.Register(Classes.FromThisAssembly().<span style="color: #333399;"><strong>Pick()</strong></span>.WithServiceAllInterfaces());}}
Notice the pick() which is very important because otherwise nothing will be registred. In this example we register every class with all interfaces . You can also be very specific like this:
123456789public class FooWindsorInstaller : IWindsorInstaller{public void Install(IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store){container.Register(Component.For<Rowan>());container.Register(Component.For<IDependency1>().ImplementedBy<Dependency1>());container.Register(Component.For<IDependency2>().ImplementedBy<Dependency2>());}}
In the above code we only register class Rowan and we are very specific to which class should be used when asked for an interface IDependency.
Normally you only register root components. All other components are automatically resolved when you initiate the root component. In MVC such root components are for example the controllers. So an example of a installer for an MVC project could be:
123456789101112131415161718192021public class ControllerInstaller : IWindsorInstaller{public void Install(IWindsorContainer container, IConfigurationStore store){// Register controllers.container.Register(Classes.FromThisAssembly().Pick().If(t => t.Name.EndsWith("Controller")).Configure(configurer => configurer.Named(configurer.Implementation.Name)).LifestylePerWebRequest());container.Register(Classes.FromAssemblyNamed("MyProject.Core").Pick().WithServiceAllInterfaces().Configure(configurer => configurer.Named(configurer.Implementation.Name)).LifestylePerWebRequest());}} - Now you are ready to use all your classes without having to worry about their dependencies. To use the class Rowan which depends on the dependencies IDependency1 and IDependency2 you use Castle Windsor Resolve method:
1var myObject = container.Resolve<Rowan>(); - Last dont forget to dispose of all your objects by calling container.Dispose(). Put this in your Application_End for example.
These are just the very basics of Castle Windsor. The framework is very powerfull and has many configuration options. Just remember that Castle Windsor is using the Three Calls Pattern (RRR) and that everything is based on Registering, Resolving and then Releasing.
TIP! Read the Basic Windsor Tutorial if you are planning on using Castle Windsor. Its really good and explains a lot like how to use Castle Windsor in MVC projects and how to replace your DefaultControllerFactory in your MVC with WindsorControllerFactory.
Hi,
This post is really useful to understand and implement the basics of IoC -> Di as well could you help me to implement the same using the config files, ie bringing the name(id), service(interface), type (classes) in the app.config or web.config.
Thanks!!! This is really helpful.
In step 3 of section “Example using Castle Windsor”, there seems explicit html tags for method Pick in the code example.
Helpful article. Thanks
Thank you very much!