Wednesday 23 November 2011

Building your own IoC Container

I have been meaning to do a series on IoC containers so I finally thought of starting with this introduction. 

Before getting into the details let me just introduce you to the problem. IoC is all about DI and object creation.

In fact you can think a little bit about an abstract factory. Except with one major difference and that is the client class never even knows about the existence of the IoC Container (factory). I found this blog where this is actually explained very nicely by a simple table:

Dependency Injection as compared with Abstract Factory.
Characteristic DI AF
Is responsible for instantiating classes? Yes Yes
Class needs to know details of the created object? No No
Class needs to explicitly request creation of desired object? No Yes
Class is dependent upon the DI/Factory that creates objects on its behalf? No Yes

Another good explanation:

From Castle Windsor's Website:

Inversion of Control is a principle used by frameworks as a way to allow developers to extend the framework or create applications using it. The basic idea is that the framework is aware of the programmer's objects and makes invocations on them.

This is the opposite of using an API, where the developer's code makes the invocations to the API code. Hence, frameworks invert the control: it is not the developer code that is in charge, instead the framework makes the calls based on some stimulus.

There is another explanation on Wikipedia

Those sites do a real good job of explaining the concept that can be hard to understand.

The most important thing to understand is that IoC Containers are JUST tools and even though they may be described as patterns your code should not depend on them and it is merely a tool to facilitate dependency injection. Their job is to remove concrete references or instantiations in the code base and restrict it to one place called the Composite root.

Now before you dive in, there are LOTS of these frameworks already written and I mean lots, at first I thought there were many, but then i found Scott Hanselman’s blog on the containers available and they are even more.

Building your own

So if there are so many ones out there and they have so many features why would you even bother?

Because when i show you how incredibly simple and little code the most basic implementation is you will get a better understanding what it is about and what you might expect out of a library if you plan to use one in the future.

And since it is only about a screen full of code it is easy to absorb.

Lets say I have some Interfaces:

Code Snippet
  1. public interface IFoo
  2.     {
  3.         void DoSomething();
  4.     }
  5.  
  6.     public interface IBar { }

IFoo is something that implements some functionality and IBar will just pretend to be some dependency.

Then I have some objects implementing Foo

Code Snippet
  1. public class FooBase : IFoo
  2.     {
  3.         private IBar _bar;
  4.  
  5.         public FooBase(IBar bar)
  6.         {
  7.             this._bar = bar;
  8.         }
  9.  
  10.         public void DoSomething()
  11.         {
  12.             Console.WriteLine(string.Format("{0} doing something to {1}"this.GetType().FullName, this._bar.GetType().FullName));
  13.         }
  14.     }
  15.  
  16.     public class FooImplementation1 : FooBase
  17.     {
  18.         public FooImplementation1(IBar bar)
  19.             : base(bar)
  20.         {
  21.         }   
  22.     }
  23.  
  24.     public class FooImplementation2 : FooBase
  25.     {
  26.         public FooImplementation2(IBar bar)
  27.             : base(bar)
  28.         {
  29.         }  
  30.     }

Then we can also create 1 or 2 dummy example IBar dependencies:

Code Snippet
  1. public class Bar1 : IBar { }
  2.  
  3. public class Bar2 : IBar { }

Now you can probably imagine that normally we would create these objects something like:

Code Snippet
  1. IFoo foo = new FooImplementation1(new Bar1());

But that is of course hardcoding all the concrete implementations and dependencies manually.

Using an IoC container it looks like this:

Code Snippet
  1. var container = new Container()
  2.     .Bind<IFoo, FooImplementation1>()
  3.     .Bind<IBar, Bar1>();

You create your container  in your composition root, and map the types to your concrete implementations.

Then you resolve your objects:

Code Snippet
  1. var foo = container.Resolve<IFoo>();
  2. foo.DoSomething();

The container knows that IFoo is mapped to concrete type FooImplementation1, and that a dependency is required to IBar, it can then also resolve that instance since we also provided it.

Here is how to build this incredibly simple container:

Code Snippet
  1. public class Container
  2.     {
  3.         Dictionary<Type, Func<object>> _resolvers;
  4.  
  5.         public Container()
  6.         {
  7.             this._resolvers = new Dictionary<Type, Func<object>>();
  8.         }
  9.  
  10.         public Container Bind<T, U>()
  11.         {
  12.             return this.Bind<T>(() => (T)this.ActivateInstance(typeof(U)));
  13.         }
  14.  
  15.         public Container Bind<T>(Func<T> resolver)
  16.         {
  17.             this._resolvers[typeof(T)] = () => resolver();
  18.             return this;
  19.         }
  20.  
  21.         public object Resolve(Type type)
  22.         {
  23.             Func<object> ctor = null;
  24.             if (this._resolvers.TryGetValue(type, out ctor))
  25.             {
  26.                 return ctor();
  27.             }
  28.             throw new Exception(string.Format("Cannot resolve type: {0}", type.FullName));
  29.         }
  30.  
  31.         public T Resolve<T>()
  32.         {
  33.             return (T)this.Resolve(typeof(T));
  34.         }
  35.  
  36.         private object ActivateInstance(Type type)
  37.         {
  38.             var constructor = type.GetConstructors()[0];
  39.             var parameters = constructor.GetParameters();
  40.             var inputParameters = new object[parameters.Length];
  41.             for (int i = 0; i < inputParameters.Length; i++)
  42.             {
  43.                 var parameter = parameters[i];
  44.                 inputParameters[i] = Resolve(parameter.ParameterType);
  45.             }
  46.             return constructor.Invoke(inputParameters);
  47.         }
  48.        
  49.     }

That’s it!, that is all the code. Of course even though this example is a little naive it may work for you just as is in the real word, will fall a bit short of the many edge cases you may run into in the real world. But that is OK, even though you could use this understanding and dive right into the more mature frameworks. Or you could extend this example and create providers or wrappers to some of the other libraries out there which can probably be a good idea if you may decide to change in the future. Even if some may argue that this is not necessary.

You will notice that there are 2 ways to bind objects first is to map an interface to a concrete class. The second is to map an interface to a lambda function that provides the concrete instance. Just adding this very simple method makes it quite a bit more flexible so you could do this:

Code Snippet
  1.  
  2. var foo3 = container
  3.     .Bind<IFoo>(() => new FooImplementation1(container.Resolve<IBar>()))
  4.     .Resolve<IFoo>();
  5.  
  6. foo3.DoSomething();

That’s it for this article. Look for future posts where I will be looking at other frameworks and cases that you will run into and want to deal with.

Tuesday 1 November 2011

Roslyn: Opening the C# Compiler

Just recently Microsoft released the Roslyn CTP. You can read more on this page, but in short this opens the C# compiler to everyone.

Previous IDE's operating on source code were attempted mostly only by the those seeking an intense sanity challenge, as you needed to parse the C# document either with your own or someone elses C# parser or eye watering migraine inducing regex.

But no more.

Roslyn now makes it possible for the man on the street to parse C# and thereby do things like write his own productivity tools as I will demonstrate now and reincarnate an old friend.

Back in the day when I worked in Delphi there was a collection of IDE productivity tool with a product called GExperts.

One of the components was ProcedureList, you would hit CTRL+G and get a popup and can quick search and jump to an object in the document.

I missed this tool in Visual Studio even though there was the navigation bar, I just didn’t like it so much and the ProcedureList just felt faster to use, but I got used to this and forgot about it.

So now this small and simple enough for my first test of Roslyn:

To get started I needed the Visual Studio SDK (I didn’t have it already) (Required by Roslyn)

And then of course Roslyn CTP

Then you can use this in any projects, just add references to the Roslyn assemblies:

image

There is a VB one too, but I will just ignore it for now.

To parse a C# document into an AST is as follows:

SyntaxTree tree = SyntaxTree.ParseCompilationUnit(sourceCode);
var root = (CompilationUnitSyntax)(tree.Root);

Then you can select the classes or any other object type as follows:

var classNodes = root.DescendentNodes()
.OfType<ClassDeclarationSyntax>();

Or any other type you want to use, so now that I can get the AST and play with it I can create the add-in.

I created a Visual Studio 2010 Add-In project , don't worry this is VERY easy just use the template wizard to create a Visual Studio Package and follow the default settings.

Once created:

I built this very rudimentary frontend WinForm:

image

(That’s fine the procedure list is more about function anyway)

Then I wrote a small amount of boiler plate code in my addin's MenuItem callback:

private void MenuItemCallback(object sender, EventArgs e)
{
var app = (EnvDTE.DTE)GetService(typeof(SDTE));
if (app.ActiveDocument != null && app.ActiveDocument.Type == "Text")
{

var selection = (TextSelection)app.ActiveDocument.Selection;
var savedOffset = selection.ActivePoint.AbsoluteCharOffset;
selection.SelectAll();
string text = selection.Text;
selection.Cancel();
selection.MoveToAbsoluteOffset(savedOffset);

var view = new FormProcedureList();
var presenter = new ProcedureListPresenter(view, text);
presenter.Load();
view.ShowDialog();

if (view.SelectedMethod != null)
{
//selection.MoveToAbsoluteOffset(view.SelectedMethod.Position);
var line = OffsetToLineNumber(text, view.SelectedMethod.Position);
selection.GotoLine(line);
}
}

My presenter simply loads the Active visual studio document and converts it to an AST, which I can then use to extract the nodes as above and display the objects:

 

public void Load()
{
List<MethodDto> methods = this.GetMethods(this.Code).ToList();
this.View.BindMethods(methods);
}

I can now quick type anything into the search box and filter and instantly jump to the piece of code

Finally this is just like a normal add-in so by default you can't hit CTRL+G and get this so I set up my hotkey in the settings:

Tools - Options:

image

This basically overwrote my Goto Line, but I was fine with that for now, but you could choose something else.

So as you can see we can build awesome productivity tools with very little effort.

I will definitely be exploring this further, and I'm sure you will see some amazing things coming from Roslyn.

You can access the source via mercurial or browse the repo here:

http://code.google.com/p/procedurelist/downloads/list

Or download the VSIX package here (just double click to install)

http://code.google.com/p/procedurelist/downloads/list