kohesive / injekt

Dependency Injection for Kotlin
MIT License
235 stars 20 forks source link

Android specific examples #18

Open mykola-dev opened 9 years ago

mykola-dev commented 9 years ago

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

apatrida commented 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.

mykola-dev commented 9 years ago

Great! Thanks. This lib definitely looks more elegant than Dagger

yoavst commented 9 years ago

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.

mykola-dev commented 9 years ago

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

yoavst commented 9 years ago

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.

mykola-dev commented 9 years ago

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.

yoavst commented 9 years ago

So what we do need to have is an easier way of creating scope and clearing them.

mykola-dev commented 9 years ago

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

yoavst commented 9 years ago

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.

mykola-dev commented 9 years ago

Yes. We can clear weakMap manually in onDestroy. Here is sample project https://github.com/deviant-studio/Injekts-demo

Pianco commented 8 years ago

When the next big update will be released?