janvladimirmostert
10/11/2022, 8:31 PMcontext(A, B, C, D, E, F, G, H, I, J)
someFunction() { ... }
with (a) {
with (b) {
with (c) {
with (d) {
with (e) {
...
with(j) {
someFunction()
}
}
}
}
}
}
I was thinking with (a & b & c & d & e & g & h & i & j)
or contexts (a, b, c, d, e, g, h, i, j)
that automatically generates that nested withs, but that's even messier
obviously I've exaggerated the number of params, but if context receivers were to be used as a replacement for dependency injection (which seems like a brilliant use-case),
I can easily see the number of params increasing as the number of services in a project increases.
For now, the obvious workaround is just stashing all those fields in a single class and doing something like this:
context(Alphabet)
fun someFunction() {
this@Alphabet.a.doSomethingWithA();
}
with(Alphabet(a = TODO(), b = TODO(), ..., z = TODO())) {
someFunction()
}
Maybe this can become
context class Alphabet(
val a: A
val b: B
...
val z: Z
)
now if you
context(Alphabet)
, it puts all of those fields in context instead of the Alphabet class itself like a data class would have done.
Also, if something has context(A)
, I can just pass the whole Alphabet
context instead of wrapping the call-site in with (this@Alphabet.a) { ... }
since Alphabet already contains A
Ben Woodworth
10/12/2022, 12:13 AMYoussef Shoaib [MOD]
10/12/2022, 4:19 AMinline fun <A, B, C, D, R> withContexts(a: A, b: B, c: C, d: D, block: context(A, B, C, D) () -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(a, b, c, d)
}
(You might need to suppress a subtyping-between-contexts error, but otherwise it works really well)elect
10/14/2022, 3:42 AM