This is the second day of my participation in the August Text Challenge.More challenges in August

What is dependency injection

Dependency injection (DI) is an object-oriented programming mode, which appears to reduce the coupling, the so-called coupling is the dependency between classes, the so-called coupling is to reduce the dependency between classes.

Dependency injection is often used in our daily programming. For example, we use dependency injection when we introduce an object of another class in a constructor, or when we set an object of a class using a set method.

Dependency injection usually takes the following forms:

  • Injection through the interface
fun main(a) {
   val aaa: ClassAAA = ClassAAA()
   ClassBBB().setClassAAA(aaa)
}
interface TestInteface{
   fun setClassAAA(aaa: ClassAAA)
}
/** * classes that depend on ClassAAA */
class ClassBBB :TestInteface {
   var aaa : ClassAAA? = null
   override fun setClassAAA(aaa: ClassAAA) {
       this.aaa = aaa
   }
}
/** * the class to be injected into */
class ClassAAA {}Copy the code
  • Injection using the set method [also the most common method]
 class ClassAAA {}class ClassBBB {
     var classA: ClassAAA? = null
     fun setClassAAA(classA: ClassAAA?). {
         this.classA = classA
     }
 }
Copy the code
  • Injection via constructor
 class ClassA(b: ClassAAA) {
   var classB: ClassAAA

   init {
       classB = b
   }
}
Copy the code
  • Inject annotations [inject]
class ClassAAA {}class ClassBBB {
     @Inject
     val classAAA: ClassAAA? = null
 }
Copy the code

Using class instantiation to implement the following example, we create a class named testwatch.kt:

fun main(a) {
    TestDagger().testFunction()
}

class TestEntity constructor(val value :String = "Not so good.")

class TestDagger {

    fun testFunction(a) {
        val test = TestEntity()
        println("The weather today${test.value}")}}Copy the code

Use dagger to implement the above logic

@Component
interface TestComponent {
    fun inject(test: TestDagger?).
}

class TestDagger {
    constructor() {
        DaggerTestComponent.builder().build().inject(this)}@Inject
    lateinit var test: TestEntity

    fun testFunction(a) {
        println("The weather today${test.value} ${test.test1}")}}class TestEntity @Inject constructor() {
    val value = "Not so good."
    val test1 = "Another property"
}
Copy the code

As you can see, dagger has no advantage at this point and requires a lot of code to implement

That’s not the original intention of Dagger, but for the sake of a large project let’s take a look at the code that Dagger automatically generates

Generate the three classes, respectively is: DaggerTestComponent. Java, TestDagger_MembersInjector. Java and TestEntity_Factory. Java

Let’s look at each of these classes

First of all see DaggerTestComponent. Java

public final class DaggerTestComponent implements TestComponent {
  private DaggerTestComponent(a) {}public static Builder builder(a) {
    return new Builder();
  }

  public static TestComponent create(a) {
    return new Builder().build();
  }

  @Override
  public void inject(TestDagger test) { injectTestDagger(test); }private TestDagger injectTestDagger(TestDagger instance) {
    TestDagger_MembersInjector.injectTest(instance, new TestEntity()); / / first place
    return instance;
  }

  public static final class Builder {
    private Builder(a) {}public TestComponent build(a) {  / / in the second place
      return newDaggerTestComponent(); }}}Copy the code

There are two main points

  • One: We passinjectTest(... ,...).willTestEntityThe class intoTestDagger_MembersInjectorMembers of the class
  • The second one builds a dagger for us with a buildDaggerTestComponentclass

Combine the two into a code is our own TestDagger. DaggerTestComponent of kt. Builder (). The build () inject (this)

Why don’t we instantiate TestEntity instead of adding @Inject so that we can get the data corresponding to the entity?

The reason for this lies in the source code and we’ll look at daggerTestComponent.java first

 TestDagger_MembersInjector.injectTest(instance, new TestEntity()); / / first place

Copy the code

As you can see above,dagger helps us implement new TestEntity()

Into the injectTest method we can see

public final class TestDagger_MembersInjector implements MembersInjector<TestDagger> {...@InjectedFieldSignature("com.eegets.frame.dagger.TestDagger.test")
  public static void injectTest(TestDagger instance, TestEntity test) { instance.test = test; }}Copy the code

As you can see, Dagger automatically sets the TestEntity we just instantiated to TestDagger’s test object, which is the test variable marked @Inject in our own TestDagger. Kt

So that’s all we can see, it’s not that we’re not instantiating, it’s that dagger is instantiated and assigned to the code that we’ve generated.

This article introduces how to implement dependency injection for Dagger and how to implement a simple instance of Dagger

The reason for writing this simple article is to provide a foundation for the next article on the access and understanding of the dependency injection implementation of Hilt.

For more information on Dagger use, please check out Dagger. Dev /