External Source

An external source is responsible for providing an answer when Kodein cannot find one.

When Kodein cannot find a binding for the required type/argument/context, then it calls the external source.

Example: an external source
val di = DI {
    externalSource = ExternalSource { key ->
        when (key.type.jvmType) { (1)
            Whatever::class.java -> when (key.argType.jvmType) { (2)
                Unit::class.java -> when (key.tag) { (3)
                    "user" -> externalFactory { existingInstance } (4)
                    null -> externalFactory { Whatever("default-value") } (4)
                    else -> null (6)
                }
                String::class.java -> when (key.tag) { (3)
                    null -> externalFactory { Whatever(it as String) } (5)
                    else -> null (6)
                }
                else -> null (6)
            }
            else -> null (6)
        }
    }
}
1 The type that is required
2 The argument type (Unit if no argument)
3 The tag (null if no tag)
4 You can return an existing instance or a new one
5 The argument has been checked to be a String, so it can be safely casted
6 Return null if the external source has no answer

The externalSource property takes an ExternalSource instance, which is a SAM interface that can be implemented by a lambda with the ExternalSource { } constructor. This ExternalSource is called every time a new Key is asked but not found. The Key itself contains information about the binding that was asked but not found.

The ExternalSource will be called only once per unknown key.

The ExternalSource must return a function (which you can easily create with the externalFactory utility function) that takes an Any? argument and returns the instance. This function will be called every time an instance is requested. Note that if no argument is provided, the argument to the lambda will be Unit.