How to implement a simple IoC Container.

I have decided to take a topic related to software development and dig deeper and write about it on weekends. It will be my weekly learning and knowledge sharing. I have myside projects but its always cool and rewarding to understand how something really works. I do not only want to be a framework user but also a Framework contributor. This can only happen if you deep deeper most of the tools of software and language you use. For this week I want to see how easy is it to implement a simple IoC container that can be used in a project.

 What is an IoC container ?
IoC stands  for Inversion of Control and represents a design pattern used in software development. Wikipedia describes it as " a style of software construction where reusable code controls the execution of problem-specific code. It carries the strong connotation that the reusable code and the problem-specific code are developed independently, which often results in a single integrated application. Inversion of control as a design guideline serves the following purposes:

  • There is a decoupling of the execution of a certain task from implementation.
  • Every module can focus on what it is designed for.
  • Modules make no assumptions about what other systems do but rely on their contracts.
  • Replacing modules has no side effect on other modules. "

 What problem does it try to solve?
 Coupling and dependencies between objects .We let some other objects inject the object when we need it hence we are inverting the control of the process .Passing interfaces into classes and not real objects makes it easy to maintain, add and extend functions of a  feature in an application.

What are the basic prerequisites of building one?
  1. You need a container class.
  2.  In the container class you need a delegate ( A function on the fly!)
  3.  You need a dictionary data structure since you need to look up for keys before sending out objects
  4. Create a function to register the interfaces
  5. Create another function to resolve the interfaces
  6. Use the Container and do something with it.

 Before looking at the code you should understand some concepts like Interfaces, Generics and Delegates in C#. The goal is not build something that I will actually use for production code but just to see and learn the core and basic aspects of an IOC container. Here is the code of the whole project.

   
    /*IOC Container main class */
    public class MyIocContainer
    {
        public delegate object CreateInstance(MyIocContainer container);

        public Dictionary Factory;

        public MyIocContainer()
        {
            this.Factory = new Dictionary();
        }

        public void RegisterInterface(CreateInstance ci)
        {
            if (ci == null)
                throw new ArgumentNullException("ci");

            if (Factory.ContainsKey(typeof(T)))
                throw new ArgumentException("Type already registered");

            Factory.Add(typeof(T), ci);
        }
         
        public T Resolve()
        {
            if (!Factory.ContainsKey(typeof(T)))
                throw new ArgumentException("Type not registered");

            // retrieve the object from the dictionary
            var creator = Factory[typeof(T)];

            // call the delegate returning the object created
            return (T)creator(this);
        }      
    }

   // Create some interfaces to use
    public interface IDownloader
    {
        void GetWebSiteContents(string url);
    }

    public interface IExtractHtmlTags
    {
        void ExtractHtmlTags(string pWebsiteHtmlP);
    }

    // Create some classes to use the interfaces 
    public class WebSiteDownLoader : IDownloader
    {
        public void GetWebSiteContents(string url)
        {   //Some code using the webclient class
            Console.WriteLine("Call using the IoC container to load a website");
        }
    }
   
    public class ExtractHtmlTag : IExtractHtmlTags
    {
        public void ExtractHtmlTags(string websiteDataStream)
        {   
            // Some code here using Regex class<.*?>
            Console.WriteLine("Call using the IoC container to extract html tags");
        }
    }

    // Usage class for the interfaces to perform task.
    public class WebSiteTagRemover
    {
        private readonly IExtractHtmlTags _extractHtml;
        private readonly IDownloader _getWebSite;

     public WebSiteTagRemover(IExtractHtmlTags eTag, IDownloader loader)
        {
           _extractHtml = eTag;
            _getWebSite = loader;
        }

     public void PrintResults()
        {
          _getWebSite.GetWebSiteContents("http://ngalatalla.blogspot.se/");
          _extractHtml.ExtractHtmlTags("website html

");
        }
    }
 
  /*Finally execute and use the container Hooray!! */
internal class Program
    {
        private static void Main(string[] args)
        {   
         //Initiate the container
            var container = new MyIocContainer();

        //Register some interfaces to be used
           container.RegisterInterface(x => new WebSiteDownLoader());
           container.RegisterInterface(x => new ExtractHtmlTag());

      //Resolve the interfaces and get the objects mapped to them
            var getContents = container.Resolve();
            var extract = container.Resolve();

        //Do stuff with the interfaces
        var webTagRemover = new WebSiteTagRemover(extract, getContents);
        webTagRemover.PrintResults();
        }
    }

Results---

If you really want to use an IoC Container in any .Net project, you do not need to implement your own. There are much better options out there. Even if you think of implementing your own, I do not think you can implement any feature or features that they do not already have. They are even more mature and free to use in your projects. Here is a list I composed for some popular ones. I use Ninject in my personal projects because it is mature and easily configured. Choose your own based on your needs.
  Happy programming !

Comments

  1. Hey my bro,
    I'm so impressed with this ooo. In fact, you can't understand my joy. I'm proud of you. You make top use of your opportunity. Good to see your blog man.

    Man, I'm preparing to rush to church. I'll be back on your blog. We have to talk about this blog

    ReplyDelete
  2. Great blog. I have been on it for some time. No new recent post for us.

    ReplyDelete
    Replies
    1. Thank you very much for your kind words. I will try to write more.

      Delete
  3. Hello Ngala, I been able to inject interfaces in my classes to take advantage of the methods defined in the interfaces. From your post you said that "Passing interfaces into classes and not real objects makes it easy to maintain, add and extend functions of a feature in an application." I am yet to appreciate the power of this implementation idea even though I am using it smoothly, can you throw me some more insights.

    ReplyDelete
    Replies
    1. There is power here and this way of coding make life easy for everybody that want to extend the code. Its one of the core patterns used in the spring java framework and even handling java entity beans in JEE new versions. It's even part of the asp.net mvc. you can read my article about passing interfaces and not real objects. Its very simple and you can start applying it today.http://ngalatalla.blogspot.se/2010/12/loose-design-with-interfaces.html

      Delete
    2. Thanks for the quick reply. I have read the post and posted a question beneath. I have applied to a program in Sweden. Your blog has been really informative to me. Your positive attitude has been remarkable and I just love that. I posted as anonymous above.

      Delete

Post a Comment

Popular posts from this blog

Building a dynamic quiz application in ASP.net MVC

Using design patterns to build part of a soccer game engine

Using recursion to do permutations