If you have used the spring framework in Java EE Development before, then you must be no stranger to dependency injection. Dependency Injection (Di:dependency injection) is one of the ways in which control inversion (ioc:inversion of controls) is implemented, and the other is dependent lookup (Dl:dependency lookup). Of course, in the spring framework, the main use of dependency injection in control inversion is this way. There is, of course, an important concept in the Spring framework in addition to dependency injection, which is aspect-oriented programming (AOP).
To put it simply, dependency injection is responsible for injecting dependent objects into the class, while the aspect-oriented programming is responsible for adding code snippets. In this blog we mainly talk about dependency injection, about AOP and dependent on the search for content, if there is a chance, will be in the back of the blog to introduce.
This blog is not implemented using the Java language, but is implemented using OBJECTIVE-C. The concrete way to implement dependency injection is to use the reflection mechanism, this blog, we use OC's reflection mechanism to look at the implementation of dependency injection in iOS development. Of course in the Java Spring Framework is the JavaBean configured in the XML file, as in the Romans, this blog we use the iOS development commonly used in plist files to store something like JavaBean, In other words, we use the plist file instead of the XML file. Nonsense less, into our subject. "
First, the implementation mechanism of dependency injection
Depending on the injection, it sounds particularly tall, but after really understanding how it works, there is nothing. The code examples used in this blog are consistent with previous examples of " policy mode " We talked about. For the previous Strategy model blog, please move to "through the FireWire" in the "strategy mode" (strategy pattern). Of course our previous example was implemented using Swift, the blog uses OC, although the language is not, but the idea is consistent. In the "policy model" we provide different weapons strategies for officers who do not pass through the policy model. And this blog, we still use this idea, but we are in accordance with the " Dependency Injection " approach to different military officers to provide different weapons strategy.
Below is a class diagram of the example we use for this blog post. Weapontype is the parent of all weapons, in which the role of the "Weapon interface" is played. All weapons are inherited from the weapontype. While the character role class relies on the Weapontype weapon interface class, all character and Weapontype have dependencies.
"Dependency Injection" literally means injecting dependency. That is, the object of the dependency is injected into the appropriate class. In the example above, character relies on the Weapontype interface, and if "dependency injection" is used to resolve this dependency, it is through the reflection mechanism ("Runtime" ) dynamically inject the object of the Weapontype subclass into the character corresponding dependency property. and the dependency information needed for reflection, we read from the plist file, and of course Java is configured from XML, which is "dependency injection."
This blog we will be based on the above-mentioned class diagram dependency, to complete the implementation of this example. Of course, in the real implementation, we use the main core content is "interface-oriented Programming", "Object-oriented polymorphism", "Reflection mechanism", "plist file reading and operation." It will be described below.
II. directory Structure of the example project
Let's take a look at the engineering structure of the examples used in this blog, which is to get an overall look at the example projects involved in this blog post. The project directory structure below is the directory structure of the examples we have covered in this blog post. The weapon folder is the weapon interface and weapon classes involved in the weapons strategy. The character folder is the directory where the weapon users are stored. The Plist file stores dependency information for a specific class that relies on the Weapontype interface for the character class. The relation class is responsible for reading the dependency information in the plist file and injecting the dependent object through the reflection mechanism into the appropriate class based on these dependency information.
Iii. contents in the Plist file
The plist file in this blog acts like the XML used to configure JavaBean in the Spring framework. Of course, the structure and form of the plist file for this blog is different from the XML in spring, but it works the same way, and it is used to describe the dependencies between classes.
Below is the content in the Plist file that is covered in this example. From the file below, we can see that there are three classes of information stored, one is Lieutenant (Lieutenant) class, one is Captain (Captain) class, the Last is Soldier (soldier) class. Each class, also known in Java, javabean,relation classes can instantiate objects of the corresponding class based on the information provided by these classes in the Plist file according to the reflection mechanism.
Let's take lieutenant as an example. In the plist file, in fact, lieutenant corresponds to this class, from the lieutenant corresponding information, Lieutenant object is instantiated by the character class, However, when instantiating, you need to assign an object of the Hk48weapon class to the object dependency property of character. Weapon. Of course, this sequence of instantiation and assignment is done by the reflection mechanism. We'll give you a concrete implementation later.
Iv. creating a class from a plist file
The relation class is an assignment that loads the contents of the corresponding plist file, and then uses the reflection mechanism to generate an object of the corresponding class based on the content it loads. The code snippet below is the relation class that loads the contents of the Plist file above so that it generates the object of the corresponding class after the content. The code snippet below creates lieutenant objects, Captain objects, and Soldier objects, respectively, based on the context provided by relation. The details are as follows.
When an object is created from the context, the fire method is called because each object has a different context, that is, because the injected dependent objects are different, so the fire method performs different results. Below is the result of running the above code as follows:
V. Using a reflection mechanism to inject dependent objects
Next we will look at how to use the reflection mechanism to inject the dependent object, that is, the concrete implementation of the relation class.
1. Provide the plist file through the initialization method
Below is the constructor for the relation class, which has a parameter, plistfilename, that is used to store plist files that rely on contextual information. When you instantiate an object, the relation class loads the context information in the file, that is, the contents of our plist file when the file is received. The specific code is shown below.
The code snippet below is the core code of this blog, generating corresponding objects based on the context information provided in the Plist file, and injecting dependent objects into the corresponding properties of the object. Of course, the underlying object is set by setter methods. After the setting is complete, return to the object that injected the dependency. The details are as follows.
Analogy with spring framework to implement dependency injection in OC