<@U0BLRBFMM> In v4 there was a way to specify a ...
# kodein
e
@salomonbrys In v4 there was a way to specify a provider for an argument for a scope (https://github.com/Kodein-Framework/Kodein-DI/blob/4.1/shared/erased/kotlin/com/github/salomonbrys/kodein/erased/EInjected.kt#L169). This was helpful when injecting a value from a scope in a class where the scope argument wasn't ready at initialization (e.g. a Fragment that needed something from an Activity scope to be injected). Is there any way to do something similar in v5 with contexts?
Copy code
abstract class MyFragment: Fragment, KodeinAware {
  private val parentKodein: Kodein by closestKodein()

  override val kodein = Kodein {
  }

  // contrived example, but whatever
  // doesn't work because activity is null
  private val presenter: MyActivityPresenter by on(context = activity).instance()

  // used to be able to do:
  // private val presenter: MyActivityPresenter by with { activity }.instance()
}
s
I think that
private val presenter : MyActivityPresenter by kodein.instance()
would work fine. Be sure to do this as well (it may have some syntax errors, but you'll get the gist):
Copy code
override val kodein = Kodein {
  extend(parentKodein)
  ... you own stuff scoped to this fragment only, if any ...
}
e
@streetsofboston Even though
MyActivityPresenter
is scoped to the Activity? Is it because it extends the parent Kodein (I forgot to copy
extend(parentKodein)
in my example)?
s
In your Activity that hosts this Fragment, you'd have to code something similar as well, much like in MyFragment.
Copy code
class MyActivity : AppComaptActivity(), KodeinAware { 
  ...
  override val kodein = Kodein {
    val parentKodein by closestKodein()
    extend(parentKodein)
    bind<MyActivityPresenter>() with singleton { MyActivityPresenter(...) }
    ...
  }
Then, if you don't plan to define on any dependencies in your Fragment, you can just access them as follows:
Copy code
abstract class MyFragment : Fragment(), KodeinAware {
  ...
   override val kodein = Kodein {
    val parentKodein by closestKodein()
    extend(parentKodein)
  }
   
  private val presenter : MyActivityPresenter by kodein.instance()
  ...
}
e
@streetsofboston the binding is defined outside of the activity because it is used in multiple activities (like I said; this is a contrived example). It's bound to a scope tied to an activity, hence
on(context = activity)
. The actual binding is:
Copy code
bind<MyActivityPresenter>() with scoped(AndroidLifecycleScope<Activity>()).singleton { ... }
I messaged the channel with my solution earlier today (although it's not a great solution).
s
Ah, I see, the
activity
possibly can be any activity, not just the one that owns the Fragment. Yep, then your solution seems to do the trick. 🙂