Open mykola-dev opened 9 years ago
I'm working on Android example for scopes, linked, inherited, etc. Next big release will have features around that, and example app.
Great! Thanks. This lib definitely looks more elegant than Dagger
Can you give example for the need for activity scope injection? I'm using injection for every functionality that doesn't belong to android UI (like db, network), and I inject those controllers to activity and fragments.
Well. Default injector stores all objects graph in the global hash map. so when you inject something into activity, it will leak. for example i want to inject Toaster class, that depends on activity context. Now i doing something like this:
special version of injectLazy that accepts scope objects as param
inline fun <reified T : Any> injectLazyAndroid(scope: InjektScope): Lazy<T> {
return lazy { scope.get(fullType<T>()) }
}
Create scope object inside activity; inject toaster:
class MainActivity : AppCompatActivity() {
val scope: InjektScope by injectLazy()
val app: App by injectLazy()
val toaster: (text: String) -> Unit by injectLazyAndroid(scope)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
inject(scope)
toaster("niiice") // use toaster
}
define extension function:
fun Activity.inject(scope: InjektScope) {
object : InjektScopedMain(scope) {
override fun InjektRegistrar.registerInjectables() {
// activity stuff
val f: (String) -> Unit = { Toast.makeText(this@inject, it, 0).show() }
addSingleton(f)
}
}
}
Not sure if i doing it correct though :) The point is: after activity destruction object graph should be destroyed as well
Is there a non-ui usage for that? You can use extension methods for such functionality (anko has toast(string)
method)
I think it has to do with #5, for clearing scope. But we still need an easier way to work with scopes.
Yes i can use extension methods for toast and for everything else, so why to use injections at all :) The problem i trying to avoid is storing whole graph in 1 global singleton hashmap. We need a way to create local graphs that depends on specific object (like activity or service or anything else with terminal lifecycle), so when object not used anymore, both object and graph can be garbage collected. And i hope example above doing exactly what i want. Have not enough time to test it yet.
So what we do need to have is an easier way of creating scope and clearing them.
Just an idea:
val weakMap: WeakHashMap<Any, InjektScope> = WeakHashMap() // key - activity or other short live object. value - scope object
custom injectLazy function
inline fun <reified T : Any, K : Any> K.injectWeakLazy(): Lazy<T> {
return lazy { weakMap.getOrPut(this, { InjektScope(DefaultRegistrar()) }).get(fullType<T>()) }
}
and use it
val toaster: (text: String) -> Unit by injectWeakLazy()
The main idea: weak references will be garbage collected in some point of time automagically Have no time to test it. Ill check later if it works
I think it is still better to have a clear method, and make scope independent of a class reference, because until it is GCed it can cause memory leak.
Yes. We can clear weakMap manually in onDestroy. Here is sample project https://github.com/deviant-studio/Injekts-demo
When the next big update will be released?
Please add more android specific stuff. For example how to implement Activity scoped injections. So when activity has been destroyed, it also should clean up objects graph