Control inversion (Ioc) and dependency injection (DI), iocdi
The IOC is called "Inversion of Control ". Dependency Injection DI, full name "Dependency Injection ".
In software development, to reduce the coupling between modules and classes, we advocate interface-based development, in implementation, we must face the question of "who" finally provides the entity class. (The objects of each layer are loosely coupled, and the objects of each layer call interfaces .)
When a class instance requires the assistance of another class instance, in the traditional program design process, there is usually a caller to create the called instance.
Then, using the dependency injection principle, the creation of the called instance is not completed by the caller, but by the IOC container. This is the meaning of "control reversal". Then, it is also called "dependency injection ".
Martin Fowler, in his famous article "Inversion of Control Containers and the Dependency Injection pattern", divides the specific Dependency Injection into three forms: constructor Injection and attribute (setting) injection and interface injection.
Habits divide it into one (type) Matching and three injection types:
- Type Matching: although we call a service through an interface (or abstract class), the service itself is still implemented in a specific service Type, this requires a type of registration mechanism to solve the matching relationship between service interfaces and service types;
- Constructor Injection: The IoC container intelligently selects and calls the appropriate Constructor to create dependent objects. If the selected constructor has the corresponding parameters, the IoC container parses the registered dependency before calling the constructor and obtains the corresponding parameter object on its own;
- Property Injection: If you need to use a Property of the dependent object, the IoC container will automatically initialize the Property after the dependent object is created;
- Method Injection: If the dependent object needs to call a Method for initialization, the IoC container will automatically call this Method after the object is created.
Create A console program and define the following interfaces (IA, IB, IC, and ID) and their implementation classes (A, B, C, and D ). In type A, three attributes B, C, and D are defined. The parameter types are IB, IC, and ID.
Where,
Attribute B is used as the parameter of the constructor.Constructor InjectionIs initialized (??);
Attribute C applies the DependencyAttribute feature, which means thatProperty InjectionMethod;
Attribute D is initialized by Initialize. The InjectionMethodAttribute feature is applied to this method, which means this isMethod injection,When object A is created by the Ioc container, Object D is automatically called.
Microsoft has a lightweight IoC framework Unity that supports constructor injection, property injection, and method injection. For C # language, because the syntax elements are much richer than other languages, there are still some tips and features for how to implement injection.
The following is an introduction:
Test class:
namespace UnityDemo{ public interface IA { } public interface IB { } public interface IC { } public interface ID { } public class A : IA { public IB B { get; set; } [Dependency] public IC C { get; set; } public ID D { get; set; } public A(IB b) { this.B = b; } [InjectionMethod] public void Initialize(ID d) { this.D = d; } } public class B : IB { } public class C : IC { } public class D : ID { }}
Configuration registration:
<?xml version="1.0" encoding="utf-8" ?><configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/> </configSections> <unity> <containers> <container name="defaultContainer"> <register type="UnityDemo.IA, UnityDemo" mapTo="UnityDemo.A, UnityDemo"/> <register type="UnityDemo.IB, UnityDemo" mapTo="UnityDemo.B, UnityDemo"/> <register type="UnityDemo.IC, UnityDemo" mapTo="UnityDemo.C, UnityDemo"/> <register type="UnityDemo.ID, UnityDemo" mapTo="UnityDemo.D, UnityDemo"/> </container> </containers> </unity> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup></configuration>
In the Main method, create an Ioc container's UnityContainer object, load configuration information to initialize it, and then call its generic Resolve method to create an object that implements the generic interface IA.
Finally, convert the returned object to type A, and check whether the properties B, C, and D are null, that is, initialization.
namespace UnityDemo{ class Program { static void Main(string[] args) { var container = new UnityContainer(); var configuration = ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection; configuration.Configure(container, "defaultContainer"); A a = container.Resolve<IA>() as A; if (null != a) { Console.WriteLine("a.B==null? {0}", a.B == null ? "Yes" : "No"); Console.WriteLine("a.C==null? {0}", a.C == null ? "Yes" : "No"); Console.WriteLine("a.D==null? {0}", a.D == null ? "Yes" : "No"); } } }}
Execution result:
Interface injection, constructor injection (attribute B), property injection (attribute C), and method injection (attribute D) are embodied respectively ).
Jack d. @ NJ USA