What is IOC
The IOC is the abbreviation for inversion of control, which translates to "inversion of controls". Simply put, the dependency of an object is controlled by a third party. Before we understand this sentence, let's review the evolution of the IOC.
The IOC has been present
The traditional way of new class
We wrote a Chinesespeaker class, he had a SayHello method and called the output console:
Class program { static void Main (string[] args) { chinesespeaker chinesespeaker= new Chinesespeaker () ; Chinesespeaker.sayhello (); } } public class Chinesespeaker {public void SayHello () { Console.WriteLine ("Hello!!! "); } }
It doesn't seem to have any problems, everything is fine, but one day the English speaker greets us and we need to create a new Britishspeaker class:
Class program { static void Main (string[] args) { //chinesespeaker chinesespeaker = new Chinesespeaker (); Chinesespeaker.sayhello (); Britishspeaker britishspeaker = new Britishspeaker (); Britishspeaker.sayhello (); } } public class Britishspeaker {public void SayHello () { Console.WriteLine ("Hello!!!"); } } //chinesespeaker the same code as above
So far, the code has exposed the problem of design principles to avoid: loose coupling (loose coupling). The program relies heavily on the actual class, which results in:
When "Japanese" and "Indians" appear, we have to modify and recompile the code. When the program code and logic is not complex, the problem is not big, but when the program gets bigger, the program ape is hard.
Interface WayTo avoid this direct dependency, we need to abstract an object or behavior into something called an interface (interface). It is like a USB jack in the computer, whether it is a USB flash drive or the mouse as long as the plug is I can use, thereby shielding the complexity.
Therefore, we change the code to:
Public interface ispeak { void SayHello (); } public class Britishspeaker:ispeak {public void SayHello () { Console.WriteLine ("Hello!!!"); } } public class Chinesespeaker:ispeak {public void SayHello () { Console.WriteLine ("Hello!!! "); } }
Because we now have the implementation and functionality of the class removed, so we can let the client dynamic to choose who SayHello
Class program { static void Main (string[] args) { //chinesespeaker chinesespeaker = new Chinesespeaker (); Chinesespeaker.sayhello (); Britishspeaker britishspeaker = new Britishspeaker (); Britishspeaker.sayhello (); Ispeak speak; if (args. Length > 0 && args[0] = = "Chinese") { speak = new Chinesespeaker (); } Else { speak = new Britishspeaker (); } Speak. SayHello (); } }
At this time we unknowingly used the principle of dependency reversal in the object-oriented six principles (DIP), high-level modules do not rely on the implementation of low-level modules, and low-layer modules rely on the interface defined by the high-rise module. Well, let's go back to the IOC and compare the two types of notation above:
- The traditional writing class in the definition of the moment has decided the specific type, his process is from top to bottom
- The use of interface is the instantiation of the class to determine the specific type, that is, when the use of the new (), his process is a new control after the
When we look at the IOC again, it means control inversion, and we can probably understand it. The traditional process of writing is from top to bottom, and the interface write rule is to determine the implementation of the class by the other classes of new (), so the flow of control is reversed.
What is di?
Using interface, the class can be used to decide which specific class to implement. So how do we do that? Then there is a new name that appears, that is, dependency injection (Dependency injection), referred to as DI. DI is available in three ways, namely, constructor injection, attribute injection, interface injection
Constructor injection
public class Printer {private Ispeak _speak; Public Printer (Ispeak Speak)//constructor Injection {_speak = speak; }} class Program {static void Main (string[] args) {//chineses Peaker chinesespeaker = new Chinesespeaker (); Chinesespeaker.sayhello (); Britishspeaker britishspeaker = new Britishspeaker (); Britishspeaker.sayhello (); Ispeak speak; if (args. Length > 0 && args[0] = = "Chinese")//{//speak = new Chinesespeaker (); }//else//{//speak = new Britishspeaker (); }//speak. SayHello (); Printer Print; if (args. Length > 0 && args[0] = = "Chinese") {print = new Printer (New ChinEsespeaker ()); } else {print = new Printer (new Britishspeaker ()); } } }
Attribute Injection
public class printer{public ispeak Speaker {get; set;}} Class program{static void Main (string[] args) {//chinesespeaker chinesespeaker = new Chinesespeaker (); Chinesespeaker.sayhello (); Britishspeaker britishspeaker = new Britishspeaker (); Britishspeaker.sayhello (); Ispeak speak; if (args. Length > 0 && args[0] = = "Chinese")//{//speak = new Chinesespeaker (); }//else//{//speak = new Britishspeaker (); }//speak. SayHello (); Printer print = new Printer (); if (args. Length > 0 && args[0] = = "Chinese") {print. Speaker = new Chinesespeaker (); } else {print. Speaker = new Britishspeaker (); } }}
Interface Injection
Interface injection public interface IPrint {void Setspeaker (ispeak speak); } public class Printer:iprint {private Ispeak _speak; public void Setspeaker (Ispeak speak) {_speak = speak; }} class Program {static void Main (string[] args) {//chineses Peaker chinesespeaker = new Chinesespeaker (); Chinesespeaker.sayhello (); Britishspeaker britishspeaker = new Britishspeaker (); Britishspeaker.sayhello (); Ispeak speak; if (args. Length > 0 && args[0] = = "Chinese") {speak = new chinesespeaker (); } else {speak = new britishspeaker (); } Printer Printer = new Printer (); Printer. Setspeaker (speak); } }
The relationship between IOC and DI
My understanding is that IOC is an idea, and Di is the way it is implemented.
IoC Container
IoC container helps us create instances dynamically while the project is running, and its main functions are as follows:
- Dynamically create and inject dependent objects
- Managing the object life cycle
- Mapping dependencies
The principle of IoC container technology is "reflection (Reflection)". The dependency is injected into the specified object using the object that reflects the dynamic creation. Common injection methods are constructor injection and attribute injection.
Service Locator Mode
Service positioning mode is also an implementation of the IOC concept. Implementation principle: Through the Servicelocator class provides a singleton to implement the Iservicelocator interface, and is responsible for managing the creation and access of registered instances. Often combined with Factory mode.
Service Locator and IOC container are the specific implementations of the IOC. The difference is that service locator does not provide the ability to manage object lifecycles
IOC container framework under the. NET Platform
ninject:http://www.ninject.org/
Castle windsor:http://www.castleproject.org/container/index.html
autofac:http://code.google.com/p/autofac/
structuremap:http://docs.structuremap.net/
unity:http://unity.codeplex.com/
spring.net:http://www.springframework.net/
Conclusion
In the course of my study of IOC, I used my knowledge and imitated Nject to implement an IOC container framework, which can be configured with FLUENTAPI and XML to help you. Project Address: Https://github.com/Khadron/Peace
IOC principle and implementation