A tiny bit of Dependency Injection and a C# delegate surprise

Posted by: Clarity Blogs: ASP.NET, on 24 Jan 2009 | View original | Bookmarked: 0 time(s)

Ive been studying dependency injection and inversion of control after seeing them mentioned, referenced and praised in too many places to ignore. From Martin Fowlers years old hand wave of approval, to the more cutting edge of seemingly everyone involved in ASP.NET MVC, this pattern has gotten a lot of good press. Microsoft has even issued its an application block for it called Unity. All of which is not to say that this must be good because x said so, but I was curious to take a deeper look.

I took a look at a simple example provided by Oren Eini aka Ayende Rahien, prolific blogger and Rhino.Mocks driving force, in a post from late 2007, Building an IoC container in 15 lines of code. He notes in later posts that this is definitely a proof of concept, but it was helpful for me to see how simple dependency injection could be. In essence his container is just a wrapper over a dictionary of constructors, keyed by type.

The container knows which concrete implementation goes with which type, but the code that uses the type does not. Therefore, the code that uses the type is not directly dependant on its concrete implementation, instead this dependency is injected' at run time by the container. So dependency injection helps you nip a large dependency tree in the bud, which is a pretty strong argument in its favor.

Ill have more to say on this topic later, and while I wont copy and paste all of Ayendes code into my post, I did want to use a trimmed down version of his code to point out an interesting bit of C# behavior I didnt know about before:

    
    //cut down version of IoC container class
    public class DemoContainer
    {
        public delegate object Creator(DemoContainer container);

        private readonly Dictionary typeToCreator
                       = new Dictionary();

        public void Register(Creator creator)
        {
            typeToCreator.Add(typeof(T), creator);
        }

        public T Create()
        {
            return (T)typeToCreator[typeof(T)](this);
        }
    }

    //calling code
    DemoContainer container = new DemoContainer();
    //registering dependencies
    container.Register(delegate
    {
        return new NHibernateRepository();
    });

    //using the container to get back the NHibernateRepository
    IRepository myRepository = container.Create();

The part of this code that I found hardest to grasp at first was that the Creator delegate is declared with a signature that expects one argument of type DemoContainer, but the anonymous delegate used to create the NHibernateRepository is actually a no argument delegate.

The usual behavior is that a delegate has to match the signature to be bound. However, as Ayendes post demonstrates, and was confirmed by some work in Visual Studio myself, anonymous delegates with no arguments are a special case in C# that can bind to any delegate with the same return type.

This is explained by an MSDN article as follows:

However, if you omit the empty parens after the delegate keyword altogether, you are defining a special kind of anonymous method, which could be assigned to any delegate with any signature

So an interesting feature of C# 2.0 and beyond that I didnt know about another benefit of reading other peoples code. Even in a 15 line example, you might learn something new.

* Ayendes code also provides a nice example of the use of closures. So Ill give him credit for using two lesser known C# features in just 15 lines.

Advertisement
Free Agile Project Management Tool from Telerik
TeamPulse Community Edition helps your team effectively capture requirements, manage project plans, assign and track work, and most importantly, be continually connected with each other.
Category: C# | Other Posts: View all posts by this blogger | Report as irrelevant | View bloggers stats | Views: 1708 | Hits: 49

Similar Posts

  • Framework Design Guidelines: Dependency Properties more
  • Putting the Silverlight Layout System to Work more
  • WPF: Read-only Dependency Properties more
  • Lost Column #2: Unsafe Image Processing more
  • A tale of two implementations more
  • ASP.NET Development "Bitness" on Windows XP 64 Bit Edition more
  • Bitmap::FromStream() issues more

News Categories

.NET | Agile | Ajax | Architecture | ASP.NET | BizTalk | C# | Certification | Data | DataGrid | DataSet | Debugger | DotNetNuke | Events | GridView | IIS | Indigo | JavaScript | Mobile | Mono | Patterns and Practices | Performance | Podcast | Refactor | Regex | Security | Sharepoint | Silverlight | Smart Client Applications | Software | SQL | VB.NET | Visual Studio | W3 | WCF | WinFx | WPF | WSE | XAML | XLinq | XML | XSD