Monday, March 9, 2009

Castle: Control Your Dependents!

Post 3 in a 101 series on the Castle IOC project called Windsor. See part one for background

What About the Dependencies?

An Ioc Container is pretty much no use if it does not resolve a components dependencies, so we will show you how this can work.

We introduce a new component, the ListWriter which use constructor based dependency injection to provider a IMessageService. This dependency is used when writing our message:

class ListWriter : IWriter
{
private readonly IMessageService messageService;
public ListWriter(IMessageService messageService)
{
this.messageService = messageService;
}
public void Write()
{
foreach (var message in messageService.GetMessages())
Console.WriteLine(message);
}
}
interface IMessageService
{
IEnumerable<string> GetMessages();
}
class GuidMessageService : IMessageService
{
public IEnumerable<string> GetMessages()
{
for (int i = 0; i < 5; i++)
{
yield return Guid.NewGuid().ToString();
}
}
}

Because we have established a obvious dependency by exposing a constructor parameter the container is smart enough to know that it is going to have to find a registered component that fits that service. This means we also have to register this new service that we are dependent on:


class Program
{
static void Main(string[] args)
{
var container = new WindsorContainer();
container.AddComponent<IWriter, ListWriter>();
container.AddComponent<IMessageService, GuidMessageService>();
var writer1 = container.Resolve<IWriter>();
writer1.Write();
Console.ReadKey();
}
}

Which when run will now resolve the IWriter service as the LiveWriter component, realise the component can not yet be constructed as it has a dependency on the IMeassgeService, so will resolve that (as the Guid Writer Component we registered on the third line of the method), inject it into the LiveWriter component and then call Write() giving the output expected; 5 random GUID in their string representation:


122eb0e3-0812-4611-a580-7cf976039a89
5a916589-f7a5-4121-9fb6-a51cf24a6f43
977ec6f9-8110-4074-b537-047f21e6a70f
a136ae03-0caf-49fb-8511-92e3f2d39446
3aa1db17-78c8-438f-84a9-91ef14753ca7

This shows that the Container can now worry about creating object with complex dependencies and deep object graphs, allowing you to have a loosely coupled application, ready for any change that may come your way.


Next up : Using XML configuration


Back to Post 2

No comments: