-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
KTP draft specs #316
Comments
Can we have something like this for named injections:
|
So where does ktp come from? And where do I specify the scope? Lets say I have the following class: class MyInjectable : MyFrameworkClass(){
@field[Inject Named("whatever")] lateinit var myNamedClass : Sth
@Inject lateinit var sthElse : SthElse
override fun onFrameworkClassInitialized() {
val scope = Toothpick.openScopes(application, this)
Toothpick.inject(scope, this)
}
} How would that look using the new api? |
I think I can answer some of you questions @PaulWoitaschek:
Note the lack of lateinit or the annotations. Another small change but with a big impact: you can use val instead of var. I think it's a good idea to go with delegated properties (https://kotlinlang.org/docs/reference/delegated-properties.html). The code looks much cleaner. I think scopes require further investigation on how they can be achieved in pure kotlin and with the new API. |
With comes from I don't mean where the name comes from but rather: where does the reference come from? If it's a top-level property we can use this only without scopes. |
I also wonder will constructor injection be affected somehow? Field injection lies more in the anti-pattern direction in the DI world, so I hope constructor injection will still work or get some new ideas for improvements too. |
For scopes, what do you think about this idea? interface ToothpickScope {
val parentScope: ToothpickScope
get() = NO_SCOPE
}
val NO_SCOPE = object : ToothpickScope {}
operator fun ToothpickScope.plus(otherScope: ToothpickScope) = when {
this === NO_SCOPE -> otherScope
otherScope === NO_SCOPE -> this
else -> TODO("implement me")
}
fun ToothpickScope.openScope() = Toothpick.openScope(this + parentScope)
fun ToothpickScope.closeScope() {
Toothpick.openScope(this + parentScope).close()
}
inline fun <reified T> ToothpickScope.getInstance(): T = openScope().getInstance(T::class.java)
inline fun <reified T> ToothpickScope.scopedInject() = object : ReadOnlyProperty<ToothpickScope, T> {
override fun getValue(thisRef: ToothpickScope, property: KProperty<*>): T {
return thisRef.getInstance(T::class.java)
}
} |
@dimsuz constructor injections are indeed preferred in Java DI frameworks, and also when we're talking about DI in general most of us think about JSR330. Not sure this applies to Kotlin though. I believe we should use the community brainpower to figure out something that's more suited for Kotlin and what this language has to offer, rather than limiting ourselves to what DI meant for Java. A DI framework is supposed to make dependency injection easy. KTP could be just that tailored specifically for Kotlin. Also I think if you like how Toothpick for java works, I believe you could still use it in Kotlin it would just be a bit different (maybe more verbose) and you would depend on a Java module. |
I think constructor injection is the preferred way for dependency injection on kotlin too. |
I can't say if Kotlin changes things at this level. But on my side, I find
construction injection quite verbose as you to type more. Just that :)
I've always preferred field injection for that reason.
But I am wondering where we're going with this. KTP is not a new library,
it s a more Kotlin friendly API for TP.
S.
…On Wed., Dec. 5, 2018, 00:08 Paul Woitaschek ***@***.*** wrote:
I think constructor injection is the preferred way for dependency
injection on kotlin too.
It's explicit. You don't have to *run* your tests to know you forgot
dependencies when refactoring.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#316 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABv33RM4vNqT6IhIWNwbIeG7lC22Dy0aks5u137kgaJpZM4ZAAJM>
.
|
Good point regarding the named injection.
|
Related to this discussion, I've proposed some TP 2.0 compatible kotlin extensions in another issue (#305) that may be of interest in defining KTP, would appreciate any feedback. |
Hey @chenthorne, I really love what you did there. The only thing I would probably do differently is to have all the Android specifics in a different artifact so it can be used with non Android projects. I'm definitely going to use the code you've written. |
@code-twister I would do exactly the same! :) Just easier to roll it into one for now to get feedback |
This is getting closed as it has been released in version 3.0.0. |
Kotlin Toothpick draft specs - WIP
Use delegate properties for field injection
We should not use annotations for field injection, instead we will use delegate properties. For example:
Moreover, there should be a way to:
Kotlin friendly API for
@Inject
annotation? and where?Generate code compatible with optional parameters (possible?)
WIP
Moreover, KTP will be based on TP 2.0 -> no registries (no configuration needed), incremental annotation processing, better scope annotations, ... (#315, #225)
Something you miss? Any suggestion? Please comment 🙂
The text was updated successfully, but these errors were encountered: