I have recently studied IOC, Di, and some open-source frameworks. I will write a simple IOC container based on my own understanding. When using a dependency injection container, we generally implement three steps:
- Create an IOC container;
- Dependency injection. A collection object is required to store the injection relationship;
- Instance for retrieving Objects Based on dependency injection;
Now, we can follow the test-driven development mode to complete a simple version of the injection container:Mincontainer
[Testmethod] <br/> Public void cannewcontainerandresolvetype () <br/>{< br/> // <br/> // todo: add test logic here <br/> // <br/> imincontainer Container = new mincontainer (); </P> <p> container. registertype (typeof (idal), typeof (oracledal); </P> <p> // var Dal = container. resolve (typeof (idal); <br/> var Dal = container. resolve <idal> (); </P> <p> assert. isnotnull (container); </P> <p> assert. isinstanceoftype (DAL, typeof (oracledal); </P> <p>}
A container of the interface type is defined when a container is created. The interface must contain the definition of abstract methods.
Public interface imincontainer: idisposable <br/>{< br/> void registertype (type tfrom, type encoding); </P> <p> Object resolve (type T ); </P> <p> tType resolve <tType> (); <br/>}< br/>
The next step is to implement this interface,
Public class mincontainer: imincontainer <br/>{< br/> private bool disposed; </P> <p> private readonly dictionary <type, typekeys> _ regkey = <br/> New Dictionary <type, typekeys> (); </P> <p> # region imincontainer members </P> <p> Public void registertype (type tfrom, type encoding) <br/>{</P> <p> typekeys TK = new typekeys () {mintype = tfrom, mininstance = createinstance (bytes)}; <br/> If (! _ Regkey. containskey (tfrom) <br/> _ regkey. add (tfrom, TK); </P> <p >}</P> <p> Public object resolve (type T) <br/>{< br/> If (_ regkey. containskey (t) <br/> return getinstance (_ regkey [T]); </P> <p> throw new exception ("type not registered" + t ); <br/>}< br/> Public tType resolve <tType> () <br/> {<br/> return (tType) Resolve (typeof (tType )); <br/> }... <br/>
Here we need a set of dictionary types to keep the registered objects
Public class typekeys <br/>{</P> <p> Public type mintype {Get; Set ;}< br/> Public object mininstance {Get; set ;} // type instance </P> <p>}
The createinstance method is used to create an instance of an object.
Private object createinstance (type T) <br/>{< br/> var ctor = T. getconstructors (). first (); <br/> var parameters = ctor. getparameters (). select (P => resolve (P. parametertype )). toarray (); <br/> return ctor. invoke (parameters); <br/>}
In the resolve method, the getinstance method is implemented as follows, mainly to obtain instances from the dictionary.
Private object getinstance (typekeys typekey) <br/>{< br/> return typekey. mininstance ?? <Br/> (typekey. mininstance = createinstance (typekey. mintype); <br/>}
Now, the simple principle-level code is complete and tested.
Test on the console:
The above code is just a simple implementation principle and requires improved generic implementation and lifecycle management, but it is also very simple. You can download the Implementation Framework Code such as unit and munq at the codeplex site.