Sometime back I posted about Dependency Injection and how it can help you to write less code and initialize dependent objects. You can read my post using the link below:
Understanding Dependency Injection
In this post I am going to use the Castle Windsor Dependency Injection Framework. First download the DI framework from here. I will be creating a very simple windows application using the MVP pattern (Modal View Presenter). There are two projects in this application. One is the Windows Forms application project and the other is the Class Library project which will be used as a Business Objects.
Here is the class diagram of the BusinessObjects project:

The main part of the code for the AddCustomerPresenter since it is dependent on the IAddCustomerView and ICustomerRepository objects.
public class AddCustomerPresenter
{
private IAddCustomerView _view;
private ICustomerRepository _repository;
public AddCustomerPresenter(IAddCustomerView view, ICustomerRepository repository)
{
_view = view;
_repository = repository;
}
}
The AddCustomerForm which is a Windows Form is used as a concrete view for the application.
public partial class AddCustomerForm : Form, IAddCustomerView
{
private AddCustomerPresenter _presenter;
public AddCustomerForm()
{
InitializeComponent();
}
public string UserName
{
get { throw new NotImplementedException(); }
}
public string Message
{
set { throw new NotImplementedException(); }
}
private void button1_Click(object sender, EventArgs e)
{
_presenter = new AddCustomerPresenter(this, new GoodCustomerRepository());
}
Our main interest is in the following line:
presenter = new AddCustomerPresenter(this, new GoodCustomerRepository());
Although this is just a single line but we can see that the AddCustomerPresenter is dependent on the creation of IAddCustomerView and the ICustomerRepository. Currently, the initialization of AddCustomerPresenter is not complicated but this can change over time.
Let’s say that we add a Service in the future then the initialization for the presenter would look something like this:
_presenter = new AddCustomerPresenter(this, new CustomerService(new GoodCustomerRepository()));
As, you can see above the dependency chain is increasing and it is getting harder for the presenter to get initialize since it is dependent on so many other objects. Let’s introduce Castle Windsor to take care of the dependencies.
Add a reference to the following assemblies:
Castle.Core
Castle.DynamicProxy
Castle.MicroKernel
Castle.Windsor
We will also need to make a small change in the AddCustomerForm windows form. Add a new constructor which takes a presenter as an argument.
public partial class AddCustomerForm : Form, IAddCustomerView
{
private AddCustomerPresenter _presenter;
public AddCustomerForm()
{
InitializeComponent();
}
public AddCustomerForm(AddCustomerPresenter presenter) : this()
{
_presenter = presenter;
}
}
Now, in the Main static method initialize the dependencies:
Application.SetCompatibleTextRenderingDefault(false);
IWindsorContainer container = new WindsorContainer();
container.AddComponent("AddCustomerPresenter", typeof(AddCustomerPresenter));
container.AddComponent("IAddCustomerView", typeof(IAddCustomerView),
typeof(AddCustomerForm));
container.AddComponent("ICustomerRepository", typeof(ICustomerRepository), typeof(CustomerRepository));
container.AddComponent("AddCustomerForm", typeof(AddCustomerForm));
var addCustomerForm = (AddCustomerForm)container[typeof(AddCustomerForm)];
Application.Run(addCustomerForm);
container.Release(addCustomerForm);
The WindsorContainer.AddComponent method is used to add dependencies. You will need to register everything that will be used to initialize dependent objects. You will also notice that we are registering the concrete types. The following code registers the ICustomerRepository and uses the concrete type CustomerRepository.
container.AddComponent("ICustomerRepository", typeof(ICustomerRepository), typeof(CustomerRepository));
When you run the application you will not that your presenter is automatically initialized. You don’t need to supply the View or the Repository because you have already registered it using Castle Windsor.
It is a good idea to move the dependencies to a configuration file. Here are all the dependencies embedded inside the App.config file.
<castle>
<components>
<component
id="AddCustomerPresenter"
type="LearningStuffSolution.BusinessObjects.Presenters.AddCustomerPresenter, LearningStuffSolution.BusinessObjects">
<parameters>
<Url>www.screencastaday.com</Url>
</parameters>
</component>
<component
id="IAddCustomerView"
service="LearningStuffSolution.BusinessObjects.Views.IAddCustomerView, LearningStuffSolution.BusinessObjects"
type="LearningStuffSolution.Windows.UI.AddCustomerForm, LearningStuffSolution.Windows.UI" />
<component
id="IBadCustomerRepository"
service="LearningStuffSolution.BusinessObjects.Repositories.ICustomerRepository, LearningStuffSolution.BusinessObjects"
type="LearningStuffSolution.BusinessObjects.Repositories.BadCustomerRepository, LearningStuffSolution.BusinessObjects" >
<component
id="IGoodCustomerRepository"
service="LearningStuffSolution.BusinessObjects.Repositories.ICustomerRepository, LearningStuffSolution.BusinessObjects"
type="LearningStuffSolution.BusinessObjects.Repositories.GoodCustomerRepository, LearningStuffSolution.BusinessObjects" />
</component>
<component
id="AddCustomerForm"
type="LearningStuffSolution.Windows.UI.AddCustomerForm, LearningStuffSolution.Windows.UI">
</component>
</components>
</castle>
And here is the code that will read the dependencies from the configuration file and initializes them.
Application.EnableVisualStyles();
IWindsorContainer container =
new WindsorContainer(
new XmlInterpreter(new ConfigResource("castle")));
// Request the component to use it
AddCustomerForm form = (AddCustomerForm)container[typeof(AddCustomerForm)];
// Use the component
Application.Run(form);
// Release it
container.Release(form);
You might be thinking that what will happen when you introduce a new parameter to any object. You can use the parameters tag inside the configuration file which will map to the actual parameter. Let’s introduce a Url property to our AddCustomerPresenter.
public class AddCustomerPresenter
{
private IAddCustomerView _view;
private ICustomerRepository _repository;
public AddCustomerPresenter(IAddCustomerView view, ICustomerRepository repository)
{
_view = view;
_repository = repository;
}
public string Url { get; set; }
}
We can initialize the Url property by wiring it up inside the configuration file:
<component
id="AddCustomerPresenter"
type="LearningStuffSolution.BusinessObjects.Presenters.AddCustomerPresenter, LearningStuffSolution.BusinessObjects">
<parameters>
<Url>www.screencastaday.com</Url>
</parameters>
</component>
That’s about it!
[Download Sample]
I also recommend that you check out the following screen casts.
Introduction to Dependency Injection Using Castle Windsor
Castle Windsor Moving Dependencies into Application Config