Friday, 17 October 2008

Isolating your Dependency Injection Container

Hello,

While searching for some background information about Dependency Injection Frameworks (aka Ioc containers ; ex. Windsor Castle, Unity, Spring.NET , StructureMap, etc) I stumbled on this posting by Chris Tavares (Unity creator) regarding the creation of a isolation layer for DI containers.

Because there are several DI containers available , the creation of an extra shield between your code and the DI container of your choice seems not a bad idea if you want to keep a maximum of freedom to swith from container to container somewhere in time. It could be that in the lifetime of an application another DI container might be more suitable for your problem at hand because of certain feature it has.

This is made possible with a generic interface that makes up the operations you can call from a DI container. So your code, when it needs a service from a DI container, only works against this interface. At application startup you of course need to hook up a real DI Container implementation with its own configuration semantics. For several DI containers ther are already adapters written that convert the generic API semantics to the DI container specific API calls.

You call read about it and download the code from the codeplex site.


Maybe some code snippets to get your appetite perhaps started?

In the following code snippet you see the creation of the Castle Windsor Container and the act of resolving an instance of a particular type.



class Program
{
static void Main(string[] args)
{
try
{
IWindsorContainer windsorContainer = CreateWindsorContainer();

ObjectCatalog.IMyObject obj = windsorContainer[typeof(ObjectCatalog.IMyObject)] as ObjectCatalog.IMyObject;

System.Console.WriteLine("Straight Windsor");
System.Console.WriteLine(obj.WhoAreYou());
System.Console.ReadLine();
}
catch (Exception ex)
{
System.Console.WriteLine(ex.Message);
System.Console.ReadLine();
}
}

private static IWindsorContainer CreateWindsorContainer()
{
IWindsorContainer windsorContainer;
windsorContainer = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));
return windsorContainer;
}
}


The Castle Windsor config section looks like this

ps: I'm using SyntaxHighLighter. The XML is not shown correctly. It always set to uppercase. I will need to look it to that. (Tips are welcome!)





name="castle"
type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />



id="idIMyObject"
service="ObjectCatalog.IMyObject, ObjectCatalog"
type="ObjectCatalog.MyObject, ObjectCatalog" />





Consequently your code is pretty heavily "connected" to the DI container implementation of Castle Windsor in variuos ways (code + config). Which isn't necessarly all bad because in the beginning of the project you choose Windsor for its abilities. But suppose you want (or you need ; consolidation, standardization , features , ...) to change to another DI container implementation

Let's rewrite everything to the Microsoft P'n'P Unity DI container.



class Program
{
static void Main(string[] args)
{
try
{

IUnityContainer unityContainer = CreateUnityContainer();

ObjectCatalog.IMyObject obj = unityContainer.Resolve();

System.Console.WriteLine("Straight Unity");
System.Console.WriteLine(obj.WhoAreYou());
System.Console.ReadLine();
}
catch (Exception ex)
{

System.Console.WriteLine(ex.Message);
System.Console.ReadLine();
}

}

private static IUnityContainer CreateUnityContainer()
{
IUnityContainer unityContainer;
unityContainer = new UnityContainer();
UnityConfigurationSection section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
section.Containers["containerUnity"].Configure(unityContainer);
return unityContainer;
}
}


The config file for Unity for the example looks like this























So besides the config information and the creation of the container, you also must change every location where you use the services of the DI container (that's usually more than than one like in the example:-)

This is where the ServiceLocator comes in. It offers a generic way to talk to your DI container. The only implementation specifics are the config information and the creation of the container. So if you would need to change one day from one DI container to another, the changes kept to a minimum (although changing a DI config info from one format to another is also not to be taken light. Maybe some XSL magic !)

So how would the example look with the ServiceLocator?



class Program
{
static void Main(string[] args)
{
string ioc ="" ;
if (args.Length==0)
{ioc="Windsor";}
else
ioc=args[0] ;

try
{

IServiceLocator myLocator = CreateLocator(ioc);

ObjectCatalog.IMyObject obj = myLocator.GetInstance();

System.Console.WriteLine("Service Locator");
System.Console.WriteLine(" Implementation : " + myLocator.GetType().ToString());
System.Console.WriteLine(obj.WhoAreYou());
System.Console.ReadLine();
}
catch (Exception ex)
{

System.Console.WriteLine(ex.Message);
System.Console.ReadLine();
}
}

private static IServiceLocator CreateLocator(string ioc)
{
IServiceLocator myLocator=null;
if (ioc=="Unity")
myLocator = new UnityServiceLocator( CreateUnityContainer());
else if (ioc=="Windsor")
myLocator = new WindsorServiceLocator(CreateWindsorContainer());
else
throw new System.ArgumentException("Only Unity or Windsor are valid arguments");

return myLocator;
}

private static IWindsorContainer CreateWindsorContainer()
{
IWindsorContainer windsorContainer;
windsorContainer = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));
return windsorContainer;
}
private static IUnityContainer CreateUnityContainer()
{
IUnityContainer unityContainer;
unityContainer = new UnityContainer();
UnityConfigurationSection section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
section.Containers["containerUnity"].Configure(unityContainer);
return unityContainer;
}
}



So your code now makes use of a DI container generic API in order to hold on to a reference to a concrete DI Container implementation and also the calls to resolve dependencies or get instances from the DI container are written in a generic manner.
The DI Container specific calls are made in the adapters (one for each concrete DI Container). So "GetInstance" will be translated to "Resolve" for the Unity Container.

Thanks for reading.

Best regards,

Alexander

Wednesday, 15 October 2008

VISUG event : ASP.NET MVC

Hello

Yesterday (14/oct/2008) , I attended a presentation on ASP.NET Model-View–Controller (MVC) framework by Maarten Balliauw that was organized by VISUG ( a Belgian .NET community). Last web development I did was in Netscape (Who?) LiveWire (What?) and I also some ASP (thus pre .NET era). So I somehow skipped ASP.Net webforms but still followed it from the side-line. So this was an excellent opportunity to keep up-to-date with web-development.

These are some points that I learned from the presentation:

  • ASP.NET MVC model is built on top of the ASP.NET framework.
  • It is something you have to install separately.
  • Fully integrated into Visual Studio
  • It is NOT a replacement for the current ASP.NET Webforms framework
  • The main goal is to allow programmers to clearly separate responsibilities according the MVC pattern. This clear separation of presentation logic, UI and the “rest” of the application is not only conceptually but also reflected in the code and project structure as created by the ASP.NET MVC project template
  • You can use ASP.NET infrastructure in an ASP.NET MVC application. Cohabitation of the webform way of working and the MVC way of working is possible. You can also use ASP.NET providers like membership and roles. You can also re-use ASP.NET session and so fort.
  • ASP.NET Server controls can be used as long as they don’t rely on the ViewState mechanism.
  • The filter-mechanism to create attributes to annotate parts of application tha can do reccuring activities for you (err handling, logging, etc)
  • A special routing mechanism for your requests is available.By default relies on a special convention of naming and structure to kick start the right controller. But you have the ability to intervene in this routing mechanism
  • Also the View parts must follow a convention (naming , folders)
  • You can more easily test the controller logic in “classic” unit test by controlling the dependencies with dependency injection and mocking frameworks. ASP.NET MVC plays along.
  • The “car and Motor-cycle” analogy : Webforms -> car , ASP.NET -> Motor-cycle. I guess it has to do with protection , speed, and so fort . Or with the fact that you can choose between them

Some questions I still have

  • Still in CTP. Maarten thinks at PDC 2008 a beta will made available and a V1 will soon follow. But how it will be packaged, I’m not sure.
  • What about a MVP style implementation of ASP.NET webforms. Don’t you also get clean(er) separation, testability of presentation logic, understandability , etc ?
  • Is the Web Client Software factory from Patterns& practices a viable alternative?
  • In the examples Maarten showed I show a lot of in-line code in the View pages. So while server controls in webforms spit out the markup. Apparently I have to do the most your-self though Maarten mentioned some tools that can help you to alter the view rendering (Nhaml)

Some questions from the audience

  • Can the controller be in separate assemblies? In the examples shown the relation between view and controller was very tight in the sense of the “actions” you can trigger from a view (so no reference dependencies). So in first line I would think this is a part of the presentation layer But according to Maarten there is someone who tampered with the routing mechanism to achieve this.
  • Hooking up Winforms in this MVC mechanisms: It is called the ASP.NET MVC framework. It uses the System.Web namespace. So in the lower parts of the framework I guess all Http-stuff (get, post, etc). Maybe the MVP pattern is better suited? Has anyone used the Smart Client Software Factory?
  • There was also a question about comparison , I believe, between Monorail , classic Web forms and ASP.NET MVC. I think this could be a valuable for many in order to have some “framework” to base a decision on what web development model to use (car-motorcycle analogy). One of the bullets is the presenation was : Not for everyone. So I guess there are some points to think about before embarking in a ASP.NET MVC implementation .

I’m sure I forgot some things from the presentation. If you have any comments or would like to add some points (benefits or concerns) , feel free to drop a line.

Visug has some more interesting sessions coming up ;

  • ASP.NET 3.5 sp1 novelties,
  • Rosario(VSTS 2010) ,
  • Entity framework & WCF and
  • a session by Juval Lowy (hardcore WCF).

Thanks for reading.

Best regards,


Alexander