Friday, November 18, 2005

Adding NanoContainer

After you have already decided to Add PicoContainer you can go a step further and use NanoContainer. NanoContainer is a complement to the PicoContainer project, providing it with additional functionality. One aspect of NanoContainer is the ability to mark your classes with an attribute that PicoContainer can use to register components.

Using NanoContainer attributes is very easy. Each of my classes need to be registered with default options (Constructor Injection, Caching); therefore, all I need to do is add the [RegisterWithContainer] attribute to each class. I add this attribute to all the classes I want registered; however, I'll only show PresenterFactory.
[RegisterWithContainer]
public class PresenterFactory
{
public Hashtable presenterHash = new Hashtable();

public PresenterFactory(IPresenter[] presenters)
{
for (int i = 0; i < presenters.Length; i++)
{
this.presenterHash[presenters[i].View.GetType()] = presenters[i];
}
}

public IView Find(Type type)
{
IPresenter presenter = (IPresenter) presenterHash[type];
presenter.Push();
return presenter.View;
}
}

After adding the [RegisterWithComponent] attribute I change the EntryPoint class implementation to use the AttributeBasedContainerBuilderFacade. The BuilderFacade will create a new instance of IMutablePicoContainer that I can use to register my UserData instance. I can also continue to use the container to get an instance of the MainPresenter.
public class EntryPoint
{
[STAThread]
static void Main()
{
ContainerBuilderFacade containerBuilderFacade = new AttributeBasedContainerBuilderFacade();
IMutablePicoContainer container = containerBuilderFacade.Build(new string[] {"SampleSmartClient.UI.dll"});
container.RegisterComponentInstance(createUser());
MainPresenter presenter = (MainPresenter) container.GetComponentInstance(typeof(MainPresenter));
Application.Run(presenter.MainForm);
}

private static UserData createUser()
{
UserData user = new UserData();
user.Name = "John Doe";
user.JobTitle = "Rockstar";
user.PhoneNumber = "212-555-1212";
user.Password = "password";
return user;
}
}


As I previously noted, using NanoContainer Attributes does add a dependency to NanoContainer. Some people are very against this idea. Personally, it seems like another case of concern over less dependency for less dependencies sake. Adding a dependency to NanoContainer should cause you no pain, but it will clean up your code. The achieved clarity in code is worth the added dependency.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.