Oren Eini

aka Ayende Rahien

Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,616
|
Comments: 51,246

Copyright ©️ Ayende Rahien 2004 — 2025

Privacy Policy · Terms
filter by tags archive
RavenDB - High-Performance NoSQL Document Database

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.

Tweet 3 comments
Tags:

Related posts that you may find interesting:

20 Oct 2007 Building an IoC container in 15 lines of code
IoC
19 Apr 2009 NHibernate Mapping -
22 Jan 2010 Rejecting Dependency Injection Inversion

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.

Markdown formatting

ESC to close

Markdown turns plain text formatting into fancy HTML formatting.

Phrase Emphasis

*italic* **bold**
_italic_ __bold__

Links

Inline:

An [example](http://url.com/ "Title")

Reference-style labels (titles are optional):

An [example][id]. Then, anywhere
else in the doc, define the link:
 [id]: http://example.com/ "Title"

Images

Inline (titles are optional):

![alt text](/path/img.jpg "Title")

Reference-style:

![alt text][id]
[id]: /url/to/img.jpg "Title"

Headers

Setext-style:

Header 1
========
Header 2
--------

atx-style (closing #'s are optional):

# Header 1 #
## Header 2 ##
###### Header 6

Lists

Ordered, without paragraphs:

1. Foo
2. Bar

Unordered, with paragraphs:

* A list item.
 With multiple paragraphs.
* Bar

You can nest them:

* Abacus
 * answer
* Bubbles
 1. bunk
 2. bupkis
 * BELITTLER
 3. burper
* Cunning

Blockquotes

> Email-style angle brackets
> are used for blockquotes.
> > And, they can be nested.
> #### Headers in blockquotes
> 
> * You can quote a list.
> * Etc.

Horizontal Rules

Three or more dashes or asterisks:

---
* * *
- - - - 

Manual Line Breaks

End a line with two or more spaces:

Roses are red, 
Violets are blue.

Fenced Code Blocks

Code blocks delimited by 3 or more backticks or tildas:

```
This is a preformatted
code block
```

Header IDs

Set the id of headings with {#<id>} at end of heading line:

## My Heading {#myheading}

Tables

Fruit |Color
---------|----------
Apples |Red
Pears	 |Green
Bananas |Yellow

Definition Lists

Term 1
: Definition 1
Term 2
: Definition 2

Footnotes

Body text with a footnote [^1]
[^1]: Footnote text here

Abbreviations

MDD <- will have title
*[MDD]: MarkdownDeep

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. Recording (18):
    29 Sep 2025 - How To Run AI Agents Natively In Your Database
  2. Webinar (8):
    16 Sep 2025 - Building AI Agents in RavenDB
  3. RavenDB 7.1 (7):
    11 Jul 2025 - The Gen AI release
  4. Production postmorterm (2):
    11 Jun 2025 - The rookie server's untimely promotion
  5. RavenDB News (2):
    02 May 2025 - May 2025
View all series

Syndication

Main feed ... ...
Comments feed ... ...
}

AltStyle によって変換されたページ (->オリジナル) /