Home:ALL Converter>How to create an instances of the class in Koin correctly?

How to create an instances of the class in Koin correctly?

Ask Time:2022-01-22T21:49:12         Author:Alexander Miashok

Json Formatter

I'm learning Koin right now and here is my trouble. When I'm trying to run a application, I am getting this error:

kt:23)
    at com.example.radioapp.ModulesKt$appModule$1$3.invoke(Modules.kt:15)
    at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:53)
    at org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:38)
    at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:110)
    at org.koin.core.scope.Scope.resolveValue(Scope.kt:254)
    at org.koin.core.scope.Scope.resolveInstance(Scope.kt:241)
    at org.koin.core.scope.Scope.get(Scope.kt:204)
    at com.example.radioapp.ModulesKt$appModule$1$4.invoke(Modules.kt:23)
    at com.example.radioapp.ModulesKt$appModule$1$4.invoke(Modules.kt:16)
    at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:53)
    at org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:38)
    at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:110)
    at org.koin.core.scope.Scope.resolveValue(Scope.kt:254)
    at org.koin.core.scope.Scope.resolveInstance(Scope.kt:241)
    at org.koin.core.scope.Scope.get(Scope.kt:204)
    at com.example.radioapp.coordinators.RadioStations.<init>(RadioStations.kt:130)
    at com.example.radioapp.ModulesKt$appModule$1$1.invoke(Modules.kt:13)
    at com.example.radioapp.ModulesKt$appModule$1$1.invoke(Modules.kt:13)
    at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:53)
    at org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:46)
    at org.koin.core.instance.SingleInstanceFactory$get$1.invoke(SingleInstanceFactory.kt:53)
    at org.koin.core.instance.SingleInstanceFactory$get$1.invoke(SingleInstanceFactory.kt:51)
    at org.koin.mp.KoinPlatformTools.synchronized(PlatformToolsJVM.kt:20)
    at org.koin.core.instance.SingleInstanceFactory.get(SingleInstanceFactory.kt:51)
    at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:110)
    at org.koin.core.scope.Scope.resolveValue(Scope.kt:254)
    at org.koin.core.scope.Scope.resolveInstance(Scope.kt:241)
    at org.koin.core.scope.Scope.get(Scope.kt:204)
    at com.example.radioapp.ModulesKt$appModule$1$3.invoke(Modules.kt:23)
    at com.example.radioapp.ModulesKt$appModule$1$3.invoke(Modules.kt:15)
    at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:53)
    at org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:38)
    at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:110)
    at org.koin.core.scope.Scope.resolveValue(Scope.kt:254)
    at org.koin.core.scope.Scope.resolveInstance(Scope.kt:241)
    at org.koin.core.scope.Scope.get(Scope.kt:204)
    at com.example.radioapp.ModulesKt$appModule$1$4.invoke(Modules.kt:23)
    at com.example.radioapp.ModulesKt$appModule$1$4.invoke(Modules.kt:16)
    at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:53)
    at org.koin.core.instance.FactoryInstanceFactory.get(FactoryInstanceFactory.kt:38)
    at org.koin.core.registry.InstanceRegistry.resolveInstance$koin_core(InstanceRegistry.kt:110)
    at org.koin.core.scope.Scope.resolveValue(Scope.kt:254)
    at org.koin.core.scope.Scope.resolveInstance(Scope.kt:241)
    at org.koin.core.scope.Scope.get(Scope.kt:204)
    at com.example.radioapp.coordinators.RadioStations.<init>(RadioStations.kt:130)
    at com.example.radioapp.ModulesKt$appModule$1$1.invoke(Modules.kt:13)
    at com.example.radioapp.ModulesKt$appModule$1$1.invoke(Modules.kt:13)
    at org.koin.core.instance.InstanceFactory.create(InstanceFactory.kt:53)
    at org.koin.core.instance.SingleInstanceFactory.create(SingleInstanceFactory.kt:46)
    at org.koin.core.instance.SingleInstanceFactory$get$1.invoke(SingleInstanceFactory.kt:53)

(yes, this is my log, the beginning of the message was truncated because it has 13k lines)

This application is a streaming app for Belarussian radio listening.

I don't know how to create instance of a ViewModel which is implementing an interface and i'm just need to do this to get the MainFragment context to my ApiImpl class (RadioStations):

RadioStations.kt

interface RadioStationsURLAPI {
    fun start(url: String)
    fun stop()
    fun getURL(id: Int): String
}

class RadioStations : KoinComponent, RadioStationsURLAPI {

    private val mp = MediaPlayer()
    val context = get<MainFragment>()

    private fun getRadioCultureURL(): String {
        return URLs.radioCulture
    }

    private fun getRadioWorldURL(): String {
        return URLs.radioWorld
    }

    private fun getRadioEnergyURL(): String {
        return URLs.radioEnergy
    }

    private fun getRadioCenterURL(): String {
        return URLs.radioCenter
    }

    private fun getRadioOneURL(): String {
        return URLs.radioOne
    }

    private fun getRadioRadiusFmURL(): String {
        return URLs.radioRadius
    }

    private fun getRadioCapitalURL(): String {
        return URLs.radioCapital
    }

    private fun getRadioBelarusURL(): String {
        return URLs.radioBelarus
    }

    private fun getRadioBelarusFmURL(): String {
        return URLs.radioBelarusFM
    }

    private fun getRadioCityFmURL(): String {
        return URLs.radioCityFM
    }

    private fun getRadioMogilevURL(): String {
        return URLs.radioMogilev
    }

    private fun getRadioBaURL(): String {
        return URLs.radioBA
    }

    private fun getRadioRocksURL(): String {
        return URLs.radioRocks
    }

    override fun getURL(id: Int): String {
        when (id) {
            R.id.radio_item_culture -> return getRadioCultureURL()
            R.id.radio_item_world -> return getRadioWorldURL()
            R.id.radio_item_energy -> return getRadioEnergyURL()
            R.id.radio_item_center -> return getRadioCenterURL()
            R.id.radio_item_one -> return getRadioOneURL()
            R.id.radio_item_radius -> return getRadioRadiusFmURL()
            R.id.radio_item_capital -> return getRadioCapitalURL()
            R.id.radio_item_belarus -> return getRadioBelarusURL()
            R.id.radio_item_belarus_fm -> return getRadioBelarusFmURL()
            R.id.radio_item_city_fm -> return getRadioCityFmURL()
            R.id.radio_item_mogilev -> return getRadioMogilevURL()
            R.id.radio_item_BA -> return getRadioBaURL()
            R.id.radio_item_rocks -> return getRadioRocksURL()
            else -> return ""
        }
    }

    override fun start(url: String) {
        val uri = Uri.parse(url)
        println(uri)
        mp.apply {
            context.context?.let { setDataSource(it, uri) }
            prepareAsync()

        }
        mp.start()
    }

    override fun stop() {
        mp.stop()
    }
}

So here is my Modules.kt for Koin

val appModule = module {
    single { RadioStations() }
    viewModel { MainViewModel(get()) }
    factory<MainViewModelInterface> { MainViewModel(get()) }
    fragment { MainFragment(get()) }
}

my MainViewModule.kt

interface MainViewModelInterface {

    val choosedRadio: BehaviorSubject<Int>
    val recoverableError: PublishSubject<String?>

}

class MainViewModel(val radioStations: RadioStations): ViewModel(), MainViewModelInterface {

    override val choosedRadio: BehaviorSubject<Int> = BehaviorSubject.create<Int>()
    override val recoverableError: PublishSubject<String?> = PublishSubject.create<String?>()


    init {
        choosedRadio
            .map {
                radioStations.getURL(it)
            }
            .observeOn(Schedulers.newThread())
            .doOnError {
                recoverableError.onNext(it.localizedMessage)
            }
            .subscribe({
                radioStations.start(it)
            }, Timber::e)
    }

}

And my MainFragment.kt

class MainFragment(val viewModel: MainViewModelInterface) : Fragment() {

    private lateinit var toolbar: androidx.appcompat.widget.Toolbar

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.toolbar_menu, menu)
        super.onCreateOptionsMenu(menu, inflater)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_main, container, false)
        // Inflate the layout for this fragment
        toolbar = view.findViewById(R.id.radio_toolbar)
        (requireActivity() as AppCompatActivity).setSupportActionBar(toolbar)

        return view
    }

    override fun onResume() {
        super.onResume()

        toolbar.setOnMenuItemClickListener {
            viewModel.choosedRadio.onNext(it.itemId)
            true
        }

        viewModel.recoverableError
            .subscribe {
                Toast.makeText(this.context, it, Toast.LENGTH_LONG).show()
            }
    }


}

How to write instances of my classes in Modules.kt? I've read the Koin documentation but still don't get it how to do this correctly.

Author:Alexander Miashok,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/70813436/how-to-create-an-instances-of-the-class-in-koin-correctly
yy