Friday, September 23, 2005

Container framework in .NET - yes - 1.1

Haven't blogged for a good while... =P

I have been looking at the System.ComponentModel namespace. It is obviously an area where I have constantly overlooked. What is in there? There is a ton in there that the Visual Studio .NET IDE extensively uses, so it means it is useless to us as developers, right? Maybe not.

Recently I have found myself interested in digging deeper into PicoContainer.NET. It allows you to design better OO business objects by decoupling your business objects from one another (through IoC). For those who aren't familiar with IoC (Inversion of Control), basically it means in this context instead of having object A to instantiate and use object B in it, object A will ask for an instance of object B in its ctor at its construction time. How it helps OO design is that now object A no longer has a irreplaceable link to object B, thus they are decoupled, and it allows us to test object A easily by either stubbing or mocking out object B.

In the above example, object A and object B are "Components". They will be put in a "Container" and Pico will automagically instantiate object B when you request for an instance of object A.

Back to the System.ComponentModel namespace, it also contains interfaces IContainer, IComponent. Now things get interesting, each IComponent is called "sited" after being added into a IContainer (like the glue between the Container and the Component). A component can now call base.Site.GetService(typeof(anotherComponent)) to access another component's functionality. For our example, in object A's ctor, it can call base.Site.GetService(typeof(ObjectB)) to retrieve an instance of object B and create itself, without having to know how to "hard create" an instance of object B.

How does it help testing? For testing object A, one can stub or mock out its Site property and provide a testing implementation when its GetService() is getting called. This pattern (or good practice) is very important to design decoupled OO systems.

So when to use what? My take is that one should use Pico in your bootstrap class (public static void Main(args[])), and since it is considered harmful to use Pico in anywhere deeper than your bootstrap class, I will consider using the System.ComponentModel stuff in everywhere else I think using a Container-Component pattern will help decoupling my design.

Some excellent reads on the topic:
[Urban Potato] Geek: System.ComponentModel
[Daniel Cazzulino] Lightweight Containers and Plugin Architectures: Dependency Injection and Dynamic Service Locators in .NET