preface

A map of Spring IOC knowledge is summarized to share with you:

Inversion of Control — In order to comply with the dependency Inversion principle, which means that high-level modules do not depend on low-level modules, they should all rely on abstractions; Abstraction should not depend on concreteness, concreteness depends on abstraction. For example, when a family had a well when they were young, people depended on Wells and groundwater for drinking water. If they moved, they would have to dig Wells again. Water pollution would lead to no water to drink, which is the reverse dependence inversion. After the introduction of waterworks, people can drink water wherever they move, just connect a pipe, local sewage pollution, waterworks can also choose other sources of water. That is, interfaces are used, but interfaces are always implemented, and coupling is inevitable.

The IOC pattern solves this problem by putting coupling into XML files and forming dependencies as needed through a container that injects the desired interface implementation into the classes that need it. Reflection should also be an implementation of IOC. IOC features a text-based configuration file that configures the relationships between application components without modifying and compiling specific code.

Dependency Injection is a mode of operation of IOC in which a required interface implementation is injected into the classes that need it. Dependency injection can be done in many ways:

Constructor Injection: The Ioc container intelligently selects and invokes the appropriate Constructor to create dependent objects. If the selected constructor has corresponding parameters, the Ioc container resolves the registered dependencies and obtains the corresponding parameter object itself before calling the constructor.

2. Property Injection: If an attribute of the dependent object needs to be used, the Ioc container will automatically initialize the attribute after the dependent object is created.

3. Method Injection: If the dependent object needs to call a Method for corresponding initialization, the Ioc container will automatically call this Method after the object is created.

Unity provides a container for objects, so how is the container indexed? That is, how are the units inside the container identified? In Unity, there are two main ways to identify a key, either directly using an interface (or base class) as an identifier key, or using a combination of an interface (or base class) and a name as an identifier key, the value of which is the concrete class.

The first is to use interfaces (or base classes) as identification keys:

// the IWaterTool can be used as an identifier, or the base class or abstract class can be used as an identifier, to obtain the registered object: container.Resolve<IWaterTool>() container.RegisterType< IWaterTool, PressWater>();Copy the code

If multiple interfaces or base class identifiers are registered in an Ioc container, which one is registered? To solve this problem, use the interface or base class and name as the identification key. Example code is as follows:

container.RegisterType<IWaterTool, PressWater>("WaterTool1"); RegisterType<IWaterTool, PressWater>("WaterTool2"); Resolve<IWaterTool>("WaterTool1"); // register dependent object WaterTool2 IWaterTool wt = container. Var list = container.ResolveAll<IWaterTool>(); // Return all objects registered with type IWaterToolCopy the code

Add name to configuration file mapping (to be verified)

<register type="IOCDependency.IWaterTool,IOCDependency" name="WaterTool1" mapTo="IOCDependency.PressWater,IOCDependency"  />Copy the code

An example of constructor injection is as follows: using constructor injection requires passing an abstract parameter in the constructor. Ioc automatically resolves the abstraction that the representation depends on and registers it with the representation.

Click “Manage NuGet Package” to install “Unity” interface that defines people, water, and how to get water.

/// </summary> public interface IPeople {void DrinkWater(); } // </summary> public interface IWaterTool {IWater returnWater(); } /// </summary> public interface IWater {}Copy the code

Create a villager class to implement the human interface.

Public class VillagePeople: IPeople {IWaterTool _pw; public class VillagePeople: IPeople {IWaterTool _pw; public VillagePeople(IWaterTool pw) { _pw = pw; Public void DrinkWater() {IWater uw = _pw.returnWater(); if (uw ! = null) {Console.WriteLine(" Water is so sweet!!" ); Console.ReadLine(); }}}Copy the code

Create groundwater class to realize water interface.

/// </summary> Public Class UndergroundWater: IWater {}Copy the code

Create pressure well class to achieve access to water interface.

// public class PressWater: IWaterTool { public IWater returnWater() { return new UndergroundWater(); }}Copy the code
{ static void Main(string[] args) { UnityContainer container = new UnityContainer(); // Create a Unity container // Register a type in the container to decide what to use for water. RegisterType< IWaterTool, PressWater>(); RegisterType< IWaterTool, PressWater>(); IPeople = container.Resolve<VillagePeople>(); people.DrinkWater(); }}Copy the code

You can also use non-generic injection as follows:

static void Main(string[] args) { UnityContainer container = new UnityContainer(); RegisterType(typeof(IWaterTool), typeof(PressWater)); IPeople = (IPeople)container.Resolve(typeof(VillagePeople)); // Return the caller people.drinkwater (); Water / /}Copy the code

An example of property injection is as follows: property injection just needs to add the [Dependency] tag in front of the property field, this time using a configuration file instead of RegisterType. Use UnityConfigurationSection Configure method to load the configuration file below registration: click on the “manage NuGet package”, install “Unity. The Container”

<? The XML version = "1.0" encoding = "utf-8"? > <configuration> <! Declare the Unity configuration section, <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Unity.Configuration" /> </configSections> <unity  xmlns="http://schemas.microsoft.com/practices/2010/unity"> <! -- containers --> <containers> <container name="defaultContainer"> -- Mapping,type= namespace, The assembly - > < register type = "IOCDependency. IWaterTool, IOCDependency mapTo =" IOCDependency. PressWater, IOCDependency "/ > <register type="IOCDependency.IPeople,IOCDependency" mapTo="IOCDependency.VillagePeople,IOCDependency" /> </container> </containers> </unity> </configuration>Copy the code

Changed villager and main program code

/// </summary> public class VillagePeople: IPeople {[Dependency]// public IWaterTool _pw {get; set; } public void DrinkWater() { Console.WriteLine(_pw.returnWater()); Console.ReadKey(); }}Copy the code
static void Main(string[] args) { UnityContainer container = new UnityContainer(); / / create the container UnityConfigurationSection configuration = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName); configuration.Configure(container, "defaultContainer");; //container.Config("Unity.config"); IPeople people = container.Resolve<IPeople>(); // Return the caller people.drinkwater (); Water / /}Copy the code

InjectionMethod is used as an attribute method, so it is only necessary to add the [InjectionMethod] flag before the method. The definition of InjectionMethod is fuzzy. Parameter, return value, and method internal object references, as an example:

// </summary> public class VillagePeople: IPeople {public IWaterTool tool; // I am an object reference public IWaterTool tool2; Public IWaterTool Tool3; [InjectionMethod] public void DrinkWater() {if (tool == null) {}} [InjectionMethod] public void DrinkWater() DrinkWater2(IWaterTool tool2) { this.tool2 = tool2; } [InjectionMethod] public IWaterTool DrinkWater3() { return tool3; }}Copy the code
static void Main(string[] args) { UnityContainer container = new UnityContainer(); / / create the container UnityConfigurationSection configuration = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName); configuration.Configure(container, "defaultContainer"); VillagePeople people = container.Resolve<IPeople>() as VillagePeople; // Return the caller console. WriteLine("people.tool == null (reference)? {0}", people.tool == null ? "Yes" : "No"); Console.WriteLine("people.tool2 == null (parameter)? {0}", people.tool2 == null ? "Yes" : "No"); Console.WriteLine("people.tool3 == null (return value)? {0}", people.tool3 == null ? "Yes" : "No"); Console.ReadKey(); }Copy the code

In fact, we understand method injection is the injection of parameter objects.

The last

I have organized a Spring series of family barrel, Java systematic information (including Java core knowledge, interview topics and the latest Internet real questions in 20 years, e-books, etc.) friends who need to pay attention to the public number can be obtained.