Hello,
first of all thanks for the lib. I'm wondering how I can inject outside a Fragment?
For example I'd like to access my Repository instance inside my ViewModel.
Thanks.
Hello StephanBg
If it's not an Android class (Activity, Fragment ...), injection is made by constructor. Be sure to provide a definition in your module and use "get()" to resolve the needed dependency.
Here is an example of how I define my presenter class in the sample-app:
https://github.com/Ekito/koin/blob/master/koin-android/koin-sample-app/src/main/kotlin/koin/sampleapp/di/all_modules.kt#L24
and the presenter class : https://github.com/Ekito/koin/blob/master/koin-android/koin-sample-app/src/main/kotlin/koin/sampleapp/weather/WeatherPresenter.kt
Hope it helps.
Hello Arnaud,
thanks for the quick response but WeatherPresenter is injected inside WeatherActivity which is an Activity.
My ViewModel is created inside a Fragment but with android.arch.lifecycle.ViewModelProviders so I'm not able to inject any object into it. I can use a Factory to pass arguments to the constructor but in the Factory I can't use inject keyword.
You can use "by inject()" in Fragment. But if your app is based on Android Lifecycle Architecture components, Koin needs more extensions to help you :/
If you have a Context or ContextApplication object around, you can use the "getKoin()" accessor, for then inject your component.
Android Lifecycle Architecture components is on the roadmap 馃憤
A factory provider could also help you (coming in 0.4.0)
Koin version 0.5.0 will bring a module to help you inject into ViewModel. Keep in touch !
@StephaneBg I'm using slightly modified version of ViewModelProviders and I'm injecting the constructor with get(). I was looking also a way to inject properties inside ViewModel.
While you are waiting for 0.5.0. have it here
context(REPORT) {
provide { CommentRepositoryImpl() } bind CommentRepository::class
provide { ReportRepositoryFirestoneImpl() } bind ReportRepository::class
provide { ReportListFragment() }
provideFactory {
val reportRepository: ReportRepository = get()
val commentRepository: CommentRepository = get()
val reportFragment : ReportListFragment = get()
val args = arrayOf(commentRepository, reportRepository)
val viewModel : ReportViewModel = ViewModelParametrizedProvider.get().of(reportFragment).with(args).get(ReportViewModel::class)
viewModel
}
}
Hi @StephaneBg
There are several ways to achieve that with the current version 0.5.2
The quick and dirty way will be to add into your ViewModel class :
val repository = StandAloneContext.koinContext.get<MyRepository>()
The cleaner way will be to write an additional function extension like this in a file named for instance KoinComponentExt.kt :
/**
* Koin component marker interface
*/
interface KoinComponent
/**
* inject lazily given dependency
*
* @param name - bean name / optional
*/
inline fun <reified T> KoinComponent.inject(name: String = "") = lazy { StandAloneContext.koinContext.get<T>(name) }
Then you just have to make your ViewModel implements the KoinComponent marker interface and that's it. You can now inject from your new marked class.
class YourViewModel : KoinComponent {
val repository by inject<MyRepository>()
...
}
val repository = StandAloneContext.koinContext.get<MyRepository>()
not working with 1.0.1
I'm trying to inject okhttp client to AppGlideModule class that's not an activity, fragment class and it cannot be added in the constructor.
Most helpful comment
val repository = StandAloneContext.koinContext.get<MyRepository>()not working with
1.0.1I'm trying to inject okhttp client to AppGlideModule class that's not an activity, fragment class and it cannot be added in the constructor.