IL implements simple IOC containers and ilioc containers
Now that I understand the knowledge between the IL interface and the dynamic class, why not experiment with the project? The first reaction is to think of the IOC container that is often said in the ordinary times. I searched for this type of articles in the garden at http://www.cnblogs.com/kklldog/p/3395641.html, so I can use the knowledge of our predecessors to find it. I will not describe the concept of IOC. If you want to know about it, Baidu.
I. Define Interfaces
First, you can customize two interfaces and implementations.
public interface IAnimal { string Cat(); string Dog(); } public class Animal:IAnimal { public string Cat() { return "I Am Cat"; } public string Dog() { return "I Am Dog"; } }
IAnimal
public interface IMail { string SendMail(); string ReceiveMail(); } public class Mail:IMail { public string SendMail() { return "Success Send"; } public string ReceiveMail() { return "Success Receive"; } }
IMail
Ii. Configuration
Here, I will directly write a method for configuration and no longer define interfaces.
public Dictionary<string,string> GetAllConfig() { Dictionary<string, string> dic = new Dictionary<string, string>(); dic.Add("IOC.Interface.IMail", "IOC.Interface.Mail,IOC"); dic.Add("IOC.Interface.IAnimal", "IOC.Interface.Animal,IOC"); return dic; }
Config
Iii. Reflection implementation
Public static object GetInstance (string InterfaceName) {// an existing object uses if (dicObj. containsKey (InterfaceName) {return dicObj [InterfaceName];} var dicConfig = new Config. config (). getAllConfig (); if (! DicConfig. containsKey (InterfaceName) {throw new Exception ("Not Configured");} var config = dicConfig [InterfaceName]; Type taskType = Type. getType (config); // var taskObj1 = CreateInstance (taskType); var taskObj = CreateInstanceByEmit (taskType); if (null = taskObj) throw new Exception ("instantiation interface error"); dicObj. add (InterfaceName, taskObj); return taskObj ;}
GetInstance
private static Object CreateInstance(Type taskType) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); object taskObj = Activator.CreateInstance(taskType); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; string elapsedTime = String.Format("{0}",ts.Ticks ); Console.WriteLine("CreateInstance RunTime " + elapsedTime); return taskObj; }
CreateInstance
The interface is passed in, and the corresponding implementation is found in the configuration list for instantiation. If it exists, use the instantiated object directly.
Iv. Emit implementation
If you want to know how Emit obtains the instantiated object corresponding to the interface, you can try it first. For example, I want to obtain the object instantiated BY THE IAnimal interface.
public IAnimal GetInterface() { var realize= new Animal(); return (IAnimal)realize; }
Obtain the following IL information through the decompilation tool.
IL explanation:
L_0001: Create a new object (constructor) to the computing stack.
L_0006-L_0007: store to a specified location before getting pushed to the computing stack (implementation can be omitted)
L_0008-L_000b: also store to the specified location and then get to push to the stack (implementation can be omitted), br. s jump to L_000b to execute (for this segment of IL does not need to use this operation)
L_000c: Return
Then we can implement it through the IL code.
Private static Object CreateInstanceByEmit (Type taskType) {Stopwatch stopWatch = new Stopwatch (); stopWatch. start (); BindingFlags defaultFlags = BindingFlags. public | BindingFlags. instance; var constructor = taskType. getConstructors (defaflflags) [0]; // obtain the default constructor var dynamicMethod = new DynamicMethod (Guid. newGuid (). toString ("N"), typeof (Object), new [] {typeof (object [])}, true); ILGenerator IL = dynamicMethod. getILGenerator (); IL. emit (OpCodes. newobj, constructor); if (constructor. reflectedType. isValueType) IL. emit (OpCodes. box, constructor. reflectedType); IL. emit (OpCodes. ret); // correlation method var func = (Func <Object>) dynamicMethod. createDelegate (typeof (Func <Object>); stopWatch. stop (); TimeSpan ts = stopWatch. elapsed; string elapsedTime = String. format ("{0}", ts. ticks); Console. writeLine ("CreateInstanceByEmit RunTime" + elapsedTime); return func. invoke ();}
CreateInstanceByEmit
5. Execution
IAnimal iMail = ServiceTaker.GetService<IOC.Interface.IAnimal>();Console.WriteLine(iMail.Cat());
The above example can be used to gain a deeper understanding of Emit, or to understand the implementation of IOC. Of course, there are other things in IOC that need to be noted. If you are interested, you are welcome to join us.
Source code: IOC
========================================================== ==================================
During Object Instantiation, it is found that the reflection execution speed is better than that of Emit. For more information, see http://kb.cnblogs.com/page/171668/ and emit in terms of performance. Why are these differences produced after learning and sharing. If you know it, give some guidance!