0

I have the following code in Kodein module

    bind<Manager>() with factory { strategy: OrderStrategyType ->
        val manager: Manager = when (strategy) {
            OrderStrategyType.VOLATILITY -> VolatilityManager()
            else -> SimpleManager()
        }

        return@factory manager
    }

where Manager is interface and VolatilityManager() and SimpleManager() are implementing it.

IntelliJ suggests to inline variable manager, if I apply suggestion I receive the code:

    bind<Manager>() with factory { strategy: OrderStrategyType ->
        return@factory when (strategy) {
            OrderStrategyType.VOLATILITY -> VolatilityManager()
            else -> SimpleManager()
        }
    }

However, while IDE detects no problems with this code, it doesn't compile with

Type inference failed: infix fun <C, A> with(binding: KodeinBinding<in C, in A, out Manager>): Unit
cannot be applied to
(Factory<Any?, OrderStrategyType, Any>)

Honestly, I don't understand compiler error. Inference looks obvious for me. Should I rewrite my code, if yes, how?

abi
  • 99
  • 8

1 Answers1

0

Regarding this code, with Kotlin 1.3.72 their is no issue.

interface A
class B: A
class C: A

bind<A>() with factory { b: Boolean ->
    when(b) {
        true -> B()
        false -> C()
   }
}

If your classes implements/extends more than one interfaces/classes type inference may not now what type you want to return.

Force cast seems to do the trick

interface A
interface X
class B: A, X
class C: A, X

bind<A>() with factory { b: Boolean ->
    when(b) {
        true -> B()
        false -> C()
    } as A
}

PS: you don't need the return@factory as when is an expression.

romainbsl
  • 534
  • 3
  • 10
  • I think I've found what causing the issue, if B and C implements KodeinGlobalAware, your code fail to compile. – abi Jul 13 '20 at 19:30
  • Yeah, I tried this before and IDE tries to simplify this code as well (to incorrect one). Probably, I should ask Jetbrains, maybe IDE can be improved. – abi Jul 19 '20 at 16:15