Click here to Skip to main content
Click here to Skip to main content

Define your own IoC container

By , 23 Mar 2012
 

This is a simple IoC Container.

Last year I was assigned to develop an IoC container for R&D purposes which made me start working with IoC Containers. I share with you here part of it as I think it might help you a lot when you develop your own container.

The Inversion of Control (IoC) and Dependency Injection (DI) patterns are all about eliminating dependencies from your code. Dependency Injection is well-known as “Inversion of Control” whose principle is – “Don’t call us, we’ll call you”. So we can say that IoC is the principle whereas DI is the way of implementation. There are three popular ways of Inversion of Control namely:

  1. Constructor Injection
  2. Method Injection
  3. Property Injection

I am not going to discuss about IoC or DI rather I want to show how to implement your own IoC Container. However if you want to know the details about IoC and DI, please have a look at this link.

Let's move to our code portion: 

public static class IoC
{
    private static readonly IDictionary<Type, Type> types = new Dictionary<Type, Type>();
    private static readonly IDictionary<Type, object> typeInstances = new Dictionary<Type, object>();
    public static void Register<TContract, TImplementation>()
    {
        types[typeof(TContract)] = typeof(TImplementation);
    }
    public static void Register<TContract, TImplementation>(TImplementation instance)
    {
        typeInstances[typeof(TContract)] = instance;
    }
    public static T Resolve<T>()
    {
        return (T)Resolve(typeof(T));
    }
    public static object Resolve(Type contract)
    {
        if (typeInstances.ContainsKey(contract))
        {
            return typeInstances[contract];
        }
        else
        {
            Type implementation = types[contract];
            ConstructorInfo constructor = implementation.GetConstructors()[0];
            ParameterInfo[] constructorParameters = constructor.GetParameters();
            if (constructorParameters.Length == 0)
            {
                return Activator.CreateInstance(implementation);
            }
            List<object> parameters = new List<object>(constructorParameters.Length);
            foreach (ParameterInfo parameterInfo in constructorParameters)
            {
                parameters.Add(Resolve(parameterInfo.ParameterType));
            }
            return constructor.Invoke(parameters.ToArray());
        }
    }
}

Now from your bootstrapper class, you need to register your class like:

Service svc= new Service ();
IoC.Register<IService , Service >(svc);

On subsequent classes, you just need to inject the Interface or class that you register like:

private IService currentSvc = null;
public LoginServices(IService  submittedService)
{
    this.currentSvc =submittedService;
}

Very very simple!!!! We love simple, don’t we?

Updated: 19 March2012

Example: Say this is my Interface,

public interface ILogger
{
    void Log(string submittedMsg);
}

The Logger class implements this interface.

public class Logger :ILogger
{
    public void Log(string submittedMsg)
    {
        if (!string.IsNullOrEmpty(submittedMsg))
        {
            Console.WriteLine(string.Format("[{0}] {1}\r\n", DateTime.Now, submittedMsg));
            Console.Read();
        }
    }
}

In this ConsoleLogger class, I inject the ILogger to its constructor,

public class ConsoleLogger
{
   private ILogger logger = null;

   public ConsoleLogger(ILogger submittedLogger)
   {
       this.logger = submittedLogger;
       this.DisplayMessage();
   }

   public void DisplayMessage()
   {
       logger.Log("Hi..See it is working!!");
   }
}

Register and Resolve options:

class Program
{
    static void Main(string[] args)
    {
        IoC.Register<ILogger, Logger>();

        IoC.Register<ConsoleLogger, ConsoleLogger>();
        ConsoleLogger objCOnsoleLogger=IoC.Resolve<ConsoleLogger>();       
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Md. Rashim uddin
Software Developer (Senior) KAZ Software Limited.
Bangladesh Bangladesh
Member
I am nothing more than a simple man with the high vision of evolving multifaceted software systems by using my technical and interpersonal skills which will complement my professional growth. I feel enjoyment to take challenges to resolve those technical problems which are yet to be solved.
 
My Blog: http://rashimuddin.wordpress.com/
 
My Email: rashimiiuc at yahoo dot com

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
SuggestionAn improvementmemberdcjpriv26 Mar '12 - 14:04 
GeneralMy vote of 5memberenamur18 Mar '12 - 19:59 
GeneralRe: My vote of 5memberMd. Rashim uddin18 Mar '12 - 20:10 
GeneralRe: My vote of 5memberMd. Rashim uddin18 Mar '12 - 20:12 
GeneralRe: My vote of 5memberenamur18 Mar '12 - 21:20 
GeneralRe: My vote of 5memberMd. Rashim uddin18 Mar '12 - 21:30 
GeneralMy vote of 5memberSaiyed Alam18 Mar '12 - 9:31 
GeneralRe: My vote of 5memberMd. Rashim uddin18 Mar '12 - 20:10 
QuestionExample PleasememberKevin Marois15 Mar '12 - 6:12 
AnswerRe: Example PleasememberMd. Rashim uddin15 Mar '12 - 8:21 
General5 - Re: Example PleasememberKevin Marois15 Mar '12 - 8:28 
GeneralRe: 5 - Re: Example PleasememberMd. Rashim uddin15 Mar '12 - 8:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 23 Mar 2012
Article Copyright 2012 by Md. Rashim uddin
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid