Is there a way to disable automatic polymorphism s...
# kodein
m
Is there a way to disable automatic polymorphism support?
Copy code
interface A
object B : A

fun main() {
	val dkodein = Kodein.direct {
		bind<B>() with instance(B)
	}

	println(dkodein.instance<A>()) // prints object B()   <--   this should not resolve!
}
r
Actually there is no such thing in Kodein-DI, you would have an error if multiple implementation of A may have been bound to the container, otherwise, Kodein-DI is looking for the closest Type that is assignable to the one that you asked for.
m
No, I have the issue the other way round:
instance<A>()
resolves to
B
(there’s only one and no binding for plain
A
). But it should not resolve at all because it’s not what the user expects.
A
must only resolve in a different Kodein context where it is explicitly bound.
👍 1
r
In my experience, this is what you should expect from a DI engine. if you have implementations for a given interface, you would expect to inject the right (and often the unique) implementation of that interface. Otherwise, DI engines may be kind of useless if their behaviour had to be simple straight forward. IMO, explicit bindings must be used when you have conflicting ones.
m
If you have multiple interfaces used by multiple classes and multiple dependency resolution contexts then I can imagine that users get confused what interfaces they can use in what resolution context and what resolves to what else. Here’s a simplified example which took some time to debug and understand:
Copy code
Kodein {
	bind<SpecialContext>() with singleton { // SpecialContext : RootContext 
		SpecialContextImpl(
			configuration = instance(), // <SpecialContextConfiguration>
			parent = instance() // <RootContext>
		)
	}
}
I should have had a
RootContext
in this scope which serves as the parent of my
SpecialContext
. Instead, Kodein reported a cyclic dependency. The actual problem was that
RootContext
wasn’t supposed to be access in this context - i.e. I was in the wrong Kodein instance. So instead Kodein resolved the instance to itself. But that was absolutely not clear from the error. Would it have said that there is no
RootContext
bound and had printed the entire module in the exception, I would’ve understand the issue much faster. I have to use a lot of sub-interfaces over multiple levels to have a good API and because I can only use a single interface as a receiver parameter in many cases. So I cannot keep interfaces completely distinct and will keep running into this issue.