Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 6,125 | Comments: 45,486

filter by tags archive

Building an IoC container in 15 lines of code

time to read 2 min | 371 words

imageI am writing this post as a result of a discussion in the ALT.Net mailing list and DI containers in Ruby. Since I promised that I would build such a thing, it made it interesting to see how far I can minimize an IoC container.

The result is, as I said, 15 lines of significant code (ignoring blank lines or line with just curly braces).

You can see the sample model on the right. It is fairly typical model, I believe. I want to get the login controller instance without having to worry about the dependencies, and I want to do it in a non invasive way.

How can we handle that?

Well, it is pretty simple, as a matter of fact, here is the full source code for the container:

public class DemoContainer
{
	public delegate object Creator(DemoContainer container);

	private readonly Dictionary<string, object> configuration 
= new Dictionary<string, object>(); private readonly Dictionary<Type, Creator> typeToCreator
= new Dictionary<Type, Creator>(); public Dictionary<string, object> Configuration { get { return configuration; } } public void Register<T>(Creator creator) { typeToCreator.Add(typeof(T),creator); } public T Create<T>() { return (T) typeToCreator[typeof (T)](this); } public T GetConfiguration<T>(string name) { return (T) configuration[name]; } }

 Not really hard to figure out, right? And the client code is as simple:

DemoContainer container = new DemoContainer();
//registering dependecies
container.Register<IRepository>(delegate
{
	return new NHibernateRepository();
});
container.Configuration["email.sender.port"] = 1234;
container.Register<IEmailSender>(delegate
{
	return new SmtpEmailSender(container.GetConfiguration<int>("email.sender.port"));
});
container.Register<LoginController>(delegate
{
	return new LoginController(
		container.Create<IRepository>(),
		container.Create<IEmailSender>());
});

//using the container
Console.WriteLine(
	container.Create<LoginController>().EmailSender.Port
	);

I should probably mention that While this handles dependency injection quite nicely, it is absolutely not what I would consider an appropriate container to use. More on that in the next post.


Comments

Sheraz

Rahien,

   just a small type

container.Configuration["email.sender.port"] = 1234;

should be

container.GetConfiguration["email.sender.port"] = 1234;

kentaromiura

mmm I think a basic ioc container must consider 3 things

1) configuration

2) lifecycle

3) registering / istantiating

so this lacks in the 2nd point, but is a clever way to use delegates

Mats Helander

Why do you have a configuration part? Why not just register a Config object and use? Would cut your IoC container down even further! :-)

/Mats

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

  1. The design of RavenDB 4.0: Physically segregating collections - one day from now
  2. RavenDB 3.5 Whirlwind tour: I need to be free to explore my data - about one day from now
  3. RavenDB 3.5 whirl wind tour: I'll have the 3+1 goodies to go, please - 5 days from now
  4. The design of RavenDB 4.0: Voron has a one track mind - 6 days from now
  5. RavenDB 3.5 whirl wind tour: Digging deep into the internals - 7 days from now

And 12 more posts are pending...

There are posts all the way to May 30, 2016

RECENT SERIES

  1. The design of RavenDB 4.0 (14):
    03 May 2016 - Making Lucene reliable
  2. RavenDB 3.5 whirl wind tour (14):
    04 May 2016 - I’ll find who is taking my I/O bandwidth and they SHALL pay
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats