Comments (27)
Yes Ok. Sorry there was a mistake in my answer.
You need to write:
val model: T by viewModel(T::class)
or val model: T by lazy {getViewModel(T::class)}
Let me write a patch 👍
from koin.
@arnaudgiuliani
Are there any elegant approach that not pass class as a parameter to the activity?
Hope this isn't too late. You can try this:
open class BaseFragment<M : ViewModel> : Fragment() {
val viewModel: M by lazy { getViewModel(viewModelClass()) }
@Suppress("UNCHECKED_CAST")
private fun viewModelClass(): KClass<M> {
// dirty hack to get generic type https://stackoverflow.com/a/1901275/719212
return ((javaClass.genericSuperclass as ParameterizedType)
.actualTypeArguments[0] as Class<M>).kotlin
}
}
from koin.
@nEdAy if use ViewDataBinding use need change 0 to 1
because ViewModel is 2 in paramaeters
open class BaseFragment<B : ViewDataBinding, M : ViewModel> : Fragment() {
val viewModel: M by lazy { getViewModel(viewModelClass()) }
@Suppress("UNCHECKED_CAST")
private fun viewModelClass(): KClass<M> {
// dirty hack to get generic type https://stackoverflow.com/a/1901275/719212
return ((javaClass.genericSuperclass as ParameterizedType)
.actualTypeArguments[1] as Class<M>).kotlin
}
}
from koin.
@fathallah92
No. I've used the following approach:
- I have a BaseActivity:
open class BaseActivity<out ViewModelType : BaseViewModel>(clazz: KClass<ViewModelType>) :
AppCompatActivity() {
val viewModel: ViewModelType by viewModel(clazz)
}
- And on each activity, I pass the viewModel class like this:
class MainActivity : BaseActivity<MainViewModel>(MainViewModel::class) {}
But I'm not coding on this project for some time (it's in production, though), so, probably there are better ways to do it.
from koin.
API has been updated to have val model: T by viewModel(<KClass<T>>)
and avoid reified types this way.
Your base activity must be like:
class Base Activity<T : ViewModel>(clazz : KClass<T>){
val model : T by viewModel(clazz)
}
We can't pass reified parameters from class.
from koin.
@arnaudgiuliani
Are there any elegant approach that not pass class as a parameter to the activity?Hope this isn't too late. You can try this:
open class BaseFragment<M : ViewModel> : Fragment() { val viewModel: M by lazy { getViewModel(viewModelClass()) } @Suppress("UNCHECKED_CAST") private fun viewModelClass(): KClass<M> { // dirty hack to get generic type https://stackoverflow.com/a/1901275/719212 return ((javaClass.genericSuperclass as ParameterizedType) .actualTypeArguments[0] as Class<M>).kotlin } }
There is a problem when using databinding at the same time.
from koin.
Your code looks good to me.
Are you shure you are compiling koin-android-architecture 0.8.2 ??
// Koin for Android Architecture Components
compile "org.koin:koin-android-architecture:0.8.2"
from koin.
The problem was the version I was using, 0.8.0. But now that I was able to import, there's another problem:
Do you guys know how should I proceed? I really like to get the viewModel instance inside my BaseActivity to handle snackbar, toast and other generic observers from my ViewModel.
from koin.
What I trying to do is receive the type of View Model as parameter and inject a new instance of this type. There's no MyViewModel. The ViewModel types would be received in a generic way. The problem is because it's an inline function with reified type, it's not allowed to receive the type like we have here. It would be amazing to be able to use like this: val myViewModel : T by viewModel(T::class)
or val myViewModel: T by viewModel()
I'm going to try to strip the injection source code and implement a ViewModelFactory to initialize it inside the BaseActivity but this would not benefit from the rest of the library features
from koin.
Are you importing correctly?
import org.koin.android.architecture.ext.viewModel
from koin.
Maybe try declaring the type in the value?
val myViewModel : MyViewModel by viewModel()
from koin.
You don't need the angle brackets for the viewmodel I believe
from koin.
Scratch that I misunderstood that your activity was generic
from koin.
What about
val myViewModel : MyViewModel<T> by viewModel()
from koin.
Hello,
we can't use generic type T
with infered Kotlin parameter :/
Best thing is to add a method to allow such declaration: val myViewModel : MyViewModel<T> by viewModel(T::class)
or something like that.
from koin.
After 2 days I had no success trying to make this work.
I'm having a hard time working with generics in kotlin, something I could do in Java very easily.
I don't want to try another libraries for dependency injection but since I'm in the beginning of a new project in the company I work for, if I can't solve this quickly I'll be forced to try another libs or maybe, write this in Java.
from koin.
Does
val myViewModel : T by viewModel()
Not work?
from koin.
fix is available in current alpha: 0.9.0-alpha-11
from koin.
It worked! Thanks very much!!! I'll try make an extension or something like that to avoid having to pass the class as a parameter but for now, that's working wonderfully!!
from koin.
Cool :) I close the issue.
from koin.
@shrpereira Did you manage to avoid having to pass the class as a parameter?
from koin.
@shrpereira You will be able to get viewModel by class with viewModelByClass()
and getViewModelByClass
. This is the final version of the API fir release 0.9.0
from koin.
@shrpereira Have you added an extension to not pass class as a parameter to the activity ?
from koin.
@arnaudgiuliani
Are there any elegant approach that not pass class as a parameter to the activity?
from koin.
Is there an example of how this is implemented on a example Fragment? I am getting a No definition found error when I use the above example. The only way I have gotten it to work was going around the lazy and doing a loadKoinModules(module{single{ExampleViewModel()}}) inside the ExampleFragment which kind of defeats the purpose.
from koin.
@arnaudgiuliani
Are there any elegant approach that not pass class as a parameter to the activity?Hope this isn't too late. You can try this:
open class BaseFragment<M : ViewModel> : Fragment() { val viewModel: M by lazy { getViewModel(viewModelClass()) } @Suppress("UNCHECKED_CAST") private fun viewModelClass(): KClass<M> { // dirty hack to get generic type https://stackoverflow.com/a/1901275/719212 return ((javaClass.genericSuperclass as ParameterizedType) .actualTypeArguments[0] as Class<M>).kotlin } }
I have figured out by myself, quite similar with your approach , thank you for answer, happy coding :D
from koin.
I did it like this
abstract class BaseFragment<VM: BaseViewModel> : Fragment() {
val viewModel: VM by lazy { getViewModel(clazz) }
abstract var clazz: KClass<VM>
}
from koin.
Related Issues (20)
- [Enhancement] Auto Replace for Deprecation not working correctly HOT 1
- activityViewModel with scoped parameters can't be injected HOT 1
- Support androidx viewmodel for kotlin multiplatform HOT 22
- State is not restored correctly when using `koinNavGraphViewModel`
- Koin 3.5 is not binary-compatible with 3.4 HOT 2
- [koin-android] broken shared view model factory when migrating from 3.5.0 -> 3.5.3 HOT 1
- Compose view model constantly returning new instances with non-root scope HOT 5
- No static method makeOptions$default(Lorg/koin/core/module/Module;ZZILjava/lang/Object;)Lorg/koin/core/definition/Options; in
- KoinAppAlreadyStartedException after changing theme HOT 5
- > Task :composeApp:compileKotlinIosSimulatorArm64 FAILED error: Could not find "org.jetbrains.compose.annotation-internal:annotation" HOT 2
- [koin-android-compose] Broken view model factory when migrating from 3.5.0 -> 3.5.3/3.5.4 HOT 6
- Upgrading Koin `3.5.3` -> `3.5.4` removes dep on `kotlin-test` HOT 1
- No sources published for various modules of Koin 3.5.4 HOT 2
- Support default value in constructor DSL
- Docs what does int mean createdAtStart, to be created at start (or when you want)
- Kotlin Multiplatform ViewModel support in Koin HOT 3
- Missing Source Code HOT 1
- Add Object support for koin annotation.
- Does koin support component lifecycle management?
- Question - activityScope and activityRetainedScope
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from koin.