Search code examples
kotlindagger

How to fix "[Dagger/MissingBinding]" in kotlin?


I'm trying to inject LatestChart in AppComponent and sloving issue with [Dagger/MissingBinding] LatestChart cannot be provided without an @Inject constructor or an @Provides-annotated method... Thanks in advance for your help

LatestChart.kt


class LatestChart {

    @Inject
    lateinit var context: Context

    @Inject
    lateinit var formatter: YearValueFormatter

    lateinit var chart: LineChart


    init {
        App.appComponent.inject(this)
    }

    fun initChart(chart: LineChart) {
        this.chart = chart

        ***

    }


    fun addEntry(value: Float, date: Float) {
        ***
        }
    }

    private fun createSet(): LineDataSet {
        ***
        }
        return set
    }
}

And AppComponent.kt



@Component(modules = arrayOf(AppModule::class, RestModule::class, MvpModule::class, ChartModule::class))
@Singleton
interface AppComponent {

***

    fun inject(chart: LatestChart)
}

Compilation error:

***AppComponent.java:8: error: [Dagger/MissingBinding] sn0w.test.crypto.chart.LatestChart cannot be provided without an @Inject constructor or an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.
public abstract interface AppComponent {
                ^
  A binding with matching key exists in component: sn0w.test.crypto.di.AppComponent
      sn0w.test.crypto.chart.LatestChart is injected at
          sn0w.test.crypto.activities.ChartActivity.latestChart
      sn0w.test.crypto.activities.ChartActivity is injected at
          sn0w.test.crypto.di.AppComponent.inject(sn0w.test.crypto.activities.ChartActivity)




Solution

  • The way you are currently trying to inject dependencies into the LatestChart is how you satisfy the dependencies in objects that won't be created by Dagger (e.g. activities). If you create the LatestChart object by yourself (just val latestCharts = LatestCharts()), you'll see that context and formatter are actually injected into this newly created instance.

    However if you want Dagger to inject a LatestChart object into another (into ChartActivity I assume based on the compilation error), you have to let Dagger know how to create its instances. There are 2 ways to achieve that:

    1. Annotate the LatestChart constructor with @Inject

    class LatestChart @Inject constructor(
        private val context: Context,
        private val formatter: YearValueFormatter
    ) {
        lateinit var chart: LineChart
    
        fun initChart(chart: LineChart) { ... }
        fun addEntry(value: Float, date: Float) { ... }
        private fun createSet(): LineDataSet { ... }
    }
    

    2. Create a provider method in one of Dagger modules

    class LatestChart(private val context: Context, private val formatter: YearValueFormatter) {
        lateinit var chart: LineChart
    
        fun initChart(chart: LineChart) { ... }
        fun addEntry(value: Float, date: Float) { ... }
        private fun createSet(): LineDataSet { ... }
    }
    
    @Module
    class LatestChartModule {
    
        @Module
        companion object {
            @JvmStatic
            @Provides
            fun provideLatestChart(context: Context, formatter: YearValueFormatter): LatestChart =
                LatestChart(context, formatter)
        }
    }