1
votes

Implémentation d'un simple exemple Dagger2

Je suis nouveau en utilisant Dagger2 (j'ai toujours utilisé Koin) et j'essaie d'implémenter un échantillon simple mais je ne sais pas vraiment ce qu'il me manque. C'est ce que j'ai obtenu jusqu'à présent.

app.gradle :

class MainActivity : AppCompatActivity() {
    @Inject
    lateinit var testClass: TestClass

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    override fun onResume() {
        super.onResume()
        val x = testClass.getRandomValueFromCTest()
    }
}

AppModule.kt : p>

class App : DaggerApplication() {
    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.builder().application(this@App).build()
    }
}

AppComponent.kt :

class TestClass @Inject constructor(private val testOperator: TestOperator) {
    fun getRandomValueFromCTest(): Int = testOperator.generateRandomNumber()
}

class TestOperator @Inject constructor() {
    fun generateRandomNumber(): Int = Random.nextInt()
}

TestClass.kt & TestOperator.kt dans le même fichier:

@Singleton
@Component(modules = [
    AndroidInjectionModule::class,
    AppModule::class
])
interface AppComponent : AndroidInjector<App> {
    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(app: App): Builder
        fun build(): AppComponent
    }
}

App.kt :

@Module
class AppModule {
    @Provides
    @Singleton
    fun provideApplication(app: App): Application = app

    @Provides
    @Singleton
    fun provideTestOperator(testOperator: TestOperator) = testOperator

    @Provides
    @Singleton
    fun provideTestClass(testClass: TestClass) = testClass

}


0 commentaires

3 Réponses :


0
votes

MainActivity doit étendre DaggerActivity , pas AppCompatActivity


1 commentaires

Ce n'est pas vrai, en fait. Il peut étendre DaggerActivity mais ce n'est pas obligatoire. Il suffit d'appeler AndroidInjection.inject (/ * ... * /) dans la méthode onCreate (/ * ... * /) .



3
votes

AppModule.kt : indiquez le contexte de l'application. Pas besoin d'écrire @singleton @provides pour vos classes Test * (vous verrez pourquoi)

class MainActivity : DaggerAppCompatActivity() {

    @Inject
    lateinit var testClass: TestClass

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    override fun onResume() {
        super.onResume()
        val x = testClass.getRandomValueFromCTest()
    }
}

AppComponent.kt : @ Component.Builder code > est obsolète IIRC. Utilisez @ Component.Factory . Et remplacez AndroidInjectionModule :: class par AndroidSupportInjectionModule :: class puisque nous utilisons dagger-android-support et android * Compat * trucs. Référez-vous ici à un nouveau module appelé ActivityModule::class.

@Module
interface ActivityModule {

    @ContributesAndroidInjector
    fun provideMainActivity(): MainActivity
}

TestClass.kt & TestOperator.kt : Depuis vous fournissaient des singletons en écrivant la méthode @singleton et @provides, je suppose que vous voulez qu'ils soient des singletons. Annotez simplement la définition de classe avec @Singleton et la dague s'en occupera. Pas besoin d'écrire des méthodes @Provides.

class App : DaggerApplication() {
    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.factory().create(this)
    }
}

App.kt : Utilisation de l'usine au lieu du générateur depuis @ Component.Builder code > est obsolète.

@Singleton
class TestClass @Inject constructor(private val testOperator: TestOperator) {
    fun getRandomValueFromCTest(): Int = testOperator.generateRandomNumber()
}

@Singleton
class TestOperator @Inject constructor() {
    fun generateRandomNumber(): Int = Random.nextInt()
}

ActivityModule.kt : Fournissez un module à dagger pour créer vos activités.

@Singleton
@Component(modules = [
    ActivityModule::class
    AndroidSupportInjectionModule::class,
    AppModule::class
])
interface AppComponent : AndroidInjector<App> {

    @Component.Factory
    abstract class Factory : AndroidInjector.Factory<App>
}

MainActivity.kt : Enfin, étendez à partir de DaggerAppCompatActivity .

@Module
class AppModule {
    @Provides
    @Singleton
    fun provideApplication(app: App): Context = app.applicationContext
}

Je pense que cela devrait fonctionner sans problème. Pour plus d'informations, vous pouvez consulter ce sample et les nouveaux documents plus simples sur dagger.dev/android a>


0 commentaires

2
votes

Vous n'avez pas reçu l'appel d'injection.

class MainActivity : AppCompatActivity() {
  @Inject
  lateinit var testClass: TestClass

  override fun onCreate(savedInstanceState: Bundle?) {
      AndroidInjection.inject(this)
      super.onCreate(savedInstanceState)
      setContentView(R.layout.activity_main)
  }


0 commentaires