1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// super lightweight portable IoC container (will compile to Portable Class Library for use in .NET, Silverlight, Windows Phone, Windows Store apps, etc.

public interface ITinyIoc
    {
        void Register<T>(Func<ITinyIoc, T> creation);
        T Resolve<T>();
        T Resolve<T>(bool createNew);
    }

public class TinyIoc : ITinyIoc
    {
        private readonly object _mutex = new object();
        private readonly Dictionary<string, Func<ITinyIoc, object>> _directives = 
            new Dictionary<string, Func<ITinyIoc, object>>();         
        private readonly Dictionary<string, object> _objects = 
            new Dictionary<string, object>(); 

        public TinyIoc()
        {
            Register<ITinyIoc>(tinyIoc => this);
        }

        public void Register<T>(Func<ITinyIoc, T> creation)
        {
            var type = typeof (T).FullName;

            if (_directives.ContainsKey(type))
            {
                return;
            }

            Monitor.Enter(_mutex);

            try
            {
                if (_directives.ContainsKey(type))
                {
                    return;
                }      
          
                _directives.Add(type, tinyIoc => creation(tinyIoc));
            }
            finally
            {
                Monitor.Exit(_mutex);
            }
        }

        public T Resolve<T>()
        {
            return Resolve<T>(false);
        }

        public T Resolve<T>(bool createNew)
        {
            var type = typeof (T).FullName;
            
            if (!_directives.ContainsKey(type))
            {
                throw new Exception(
                    string.Format(
                    "No way to resolve type {0}",
                    type));
            }
            
            if (createNew)
            {
                return (T)_directives[type](this);
            }

            if (_objects.ContainsKey(type))
            {
                return (T) _objects[type];
            }

            Monitor.Enter(_mutex);

            try
            {
                if (_objects.ContainsKey(type))
                {
                    return (T)_objects[type];
                }                

                var instance = _directives[type](this);

                _objects.Add(type, instance);

                return (T)instance;
            }
            finally
            {
                Monitor.Exit(_mutex);
            }
        }
    }

// Example registration:
Ioc = new TinyIoc();
Ioc.Register<IStorageUtility>(ioc => new StorageUtility());
Ioc.Register<IApplicationContext>(ioc => new ApplicationContext());
Ioc.Register<IDialog>(ioc => new Dialog());
Ioc.Register<ISyndicationHelper>(ioc => new SyndicationHelper(ioc.Resolve<IDialog>()));
Ioc.Register(ioc => new BlogDataSource(ioc.Resolve<IStorageUtility>(),
   ioc.Resolve<IApplicationContext>(),
   ioc.Resolve<IDialog>(),
   ioc.Resolve<ISyndicationHelper>()));   

// Example use:
public BlogDataSource DataSource
        {
            get { return Ioc.Resolve<BlogDataSource>(); }
        }