Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to inject a fragment/activity? (circular dependency) #18

Closed
afjoseph opened this issue Nov 13, 2017 · 3 comments
Closed

How to inject a fragment/activity? (circular dependency) #18

afjoseph opened this issue Nov 13, 2017 · 3 comments

Comments

@afjoseph
Copy link

Hey!

This is not your typical situation but please humour me :)

How can an activity/application/fragment be injected as a dependency?

Assuming I have a class AudioPlayer:

class AudioPlayer(private val context: Activity) {
    fun doToast() {
        Toast.makeText(context, "Running Audio player...", Toast.LENGTH_SHORT).show()
    }
}

Which I'll need to inject inside MainActivity:

class MainActivity : BaseActivity() {
    override val contextName = "MainActivity"

    val audioPlayer by inject<AudioPlayer>()

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

        audioPlayer.doToast()
    }
}

How would I provide MainActivity as a dependency for AudioPlayer?

Here is the app module class:

fun appModules() = listOf(applicationModule())

class applicationModule : AndroidModule() {
    override fun context() = applicationContext {
        context(name = "MainActivity") {
            provide { AudioPlayer(get()) }
        }
}
@arnaudgiuliani
Copy link
Member

Hello @obaied

your are here in a circular dependency situation. The best way to handle it by property or a function and not directly by constructor. Bind MainActivity <-> AudioPlayer in 2 times.

I propose you something like:

add the contextproperty

class AudioPlayer() {
    lateinit var context: Activity
    fun doToast() {
        Toast.makeText(context, "Running Audio player...", Toast.LENGTH_SHORT).show()
    }
}

bind lately this contextproperty

class MainActivity : BaseActivity() {
    override val contextName = "MainActivity"

    val audioPlayer by inject<AudioPlayer>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_layout)
        audioPlayer.context = this
        audioPlayer.doToast()
    }
}

no need to inject context in constructor

fun appModules() = listOf(applicationModule())

class applicationModule : AndroidModule() {
    override fun context() = applicationContext {
        context(name = "MainActivity") {
            provide { AudioPlayer() }
        }
}

Other point: if you audio player just need a context, you can inject the androidContext directly.

@arnaudgiuliani arnaudgiuliani changed the title How to inject a fragment/activity? How to inject a fragment/activity? (circular dependency) Nov 14, 2017
@afjoseph
Copy link
Author

Got it! Thanks @arnaudgiuliani. I was just trying to see if Koin can automatically inject custom Android components (like Dagger).
Great, great library. I'm making my new app with it!

Cheers!

@arnaudgiuliani
Copy link
Member

Nice 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants