1

I am new to dagger 2. I was making a CarComponent on kotlin, I was trying to call my DaggerCarComponent with horsePower value without calling petrolEngineModule. the following is my code :

import dagger.BindsInstance
import dagger.Component
import javax.inject.Singleton

@Component (
    modules = [WheelModule::class, PetrolEngineModule::class]
)
interface CarComponent {

    fun getCar(): Car

    fun inject(mainActivity: MainActivity)

    @Component.Builder
    interface Builder {

        @BindsInstance
        fun horsePower(horsePower : Int) : Builder

        fun build(): CarComponent
    }
}

this is PetrolEngine.kt:

package com.example.daggerapp

import android.util.Log
import javax.inject.Inject

class PetrolEngine : Engine {

    private var horsePower : Int

    @Inject constructor(horsePower: Int){
        this.horsePower = horsePower
    }

    override fun start() {
        Log.d("Engine", "Broom..., horsePower: ${this.horsePower}")
    }
}

this is PetrolEngineModule.kt:

package com.example.daggerapp

import dagger.Module
import dagger.Provides
import javax.inject.Inject

@Module
class PetrolEngineModule {

    private var horsePower: Int

    @Inject constructor(horsePower: Int) {
        this.horsePower = horsePower
    }

    @Provides
    fun provideHorsePower(): Int {
        return horsePower
    }

    @Provides
    fun provideEngine(engine: PetrolEngine): Engine
    {
        return engine
    }
}

I added the DaggerComponent here as DaggerCarComponent :

package com.example.daggerapp

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import javax.inject.Inject

class MainActivity : AppCompatActivity() {
    @Inject
    lateinit var car:Car

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

        val daggerCar: CarComponent = DaggerCarComponent.builder().petrolEngineModule(PetrolEngineModule(140)).build()
        daggerCar.inject(this)

        Log.d("Car instance", "$car")
        car.drive()
    }
}

I was following this tutorial: https://www.youtube.com/watch?v=3tIvekCTSJg&list=PLrnPJCHvNZuA2ioi4soDZKz8euUQnJW65&index=8

SuvodipMondal
  • 87
  • 1
  • 8
  • Hey does it throw any exceptions when you build – nkoroi Jan 24 '20 at 09:23
  • No exceptions, this is the error I'm getting right now this : error: @Component.Builder is missing setters for required modules or components: [com.example.daggerapp.PetrolEngineModule] – SuvodipMondal Jan 24 '20 at 10:27
  • Hi, @SuvodipMondal welcome to SO Community. Can you please add the code where you initialize the DaggerComponent. – Muhammad Farhan Jan 24 '20 at 12:49

3 Answers3

0

In your Builder:

@BindsInstance
    Builder horsePower(@Named("horse_power") int horsePower);

After this you will be able to pass horsePower from MainActivity without passing instance of PetrolEngineModule.And same way in ur PetrolEngine constructor:

@Inject
public PetrolEngine(@Named("horse_power") int horsePower) {
    this.horsePower = horsePower;
}

And in your PetrolEngineModule u can remove everything and just leave @Provides for PetrolEngine.

Prateek Kumar
  • 321
  • 1
  • 3
  • 16
  • No, I want to omit the explicit initialization of the PetrolEngineModule – SuvodipMondal Jan 27 '20 at 06:37
  • I don't know what's wrong happening to this. I am still getting error, ohttps://github.com/smondal229/daggerAndroid.git this is my repository link – SuvodipMondal Jan 27 '20 at 13:31
  • btw plz remove provideHorsePower and constructor from your PetrolEngineModule.Not required anymore because u are passing horsePower already – Prateek Kumar Jan 27 '20 at 13:36
  • I still have to mention the module explicitly, @Component.builder setter method is not being bound correctly, if you check the repo you will find it – SuvodipMondal Jan 28 '20 at 06:10
  • Because u still have constructor in your PetrolEngineModule.In my previous comment i told u to remove provideHorsePower and constructor from ur PetrolEngineModule – Prateek Kumar Jan 28 '20 at 06:59
0

Remove @Inject in the module class, cause that what @BindsInstance is doing when pass horsePower it in @Component.Builder

nkoroi
  • 93
  • 6
  • either way my statement was correct that you are not supposed to annotate a module with @Inject and please make your responses prompt when you ask for help – nkoroi Jan 30 '20 at 16:42
0

Just an optimization for future viewers. Just replace the existing code with this. Now Dagger will not create the --Provide-- class to provide the instance of PetrolEngine.

Please improve the code if you find anything wrong.


    @Module
    abstract class PetrolEngineModule {

        @Binds
        abstract fun bindEngine(engine: PetrolEngine): Engine
    }

Anil
  • 11
  • 2