Different implementations of an interface can be distinguished by string identifiers (aka "names"). This is prone to spelling errors. This problem could be avdoided by defining strings constants, but it encourages to just use strings in place.
I suggest to add a Qualifier interface of which implementing objects could be used instead of strings to identifiy a certain implementation.
interface Qualifier // part of Koin
object Default : Qualifier // define your own qualifier
single<Service>(Default) { ServiceImpl() } // usage
The qualifier should be usebale in other places, too.
Alternatives
Annotations like in CDI could be used too, but they wouldn't fit to the current Koin programming model.
And for scope ids too.
I was thinking about a named<>() function to fulfill any type as a name.
What do you think? @erickok @helmbold
single<Service>(named<Default>()) { ServiceImpl() }
else imagine instead a type qualifier overload function for each API needed :/
It's a good alternative, yes. I suppose that is similar to the scope<ClassName> Koin already has for scoping. However, you can also reverse this logic and have the name be a Qualifier with a helper function named("default") which would return an instance for uniqueness, e.g.
class NamedQualifier(val name: String)
fun named(name: String) = NamedQualifier(name)
single<Service>(named("default")) { ServiceImpl() }
@erickok good idea. I can add this to the current beta devs 馃憤
I'm reviewing Scope API to make it very simple to use. I'm not far from final proposal. With qualifiers will be perfect!
@arnaudgiuliani What would be the return type of the suggested named method? Would just translate the object in a string? I'd prefer to enforce objects of the type Qualifier at the API level for the sake of robustness and clarity.
The suggestion of @erickok is essentially what Guice does with @Named: a typed qualifier is the default, but you can circumvent this approach by using named qualifiers, which are basically wrapped strings. However the default should be a properly typed qualifier in my opinion.
The class NamedQualifier should implement Qualifier:
class NamedQualifier(val name: String) : Qualifier
this is it, all API now is based on Qualifier instead of String. Check beta-3
I just qualified a call class with kotline :
single(named("core")) {
retrofit(get(), "http://yourweb.org/api")
}
single {
get<Retrofit>(qualifier = named("core")).create(RetrofitServiceInterface::class.java)
}
I'm happy that qualifiers are available now. However, this feature lacks documentation. The documentation talks only about about named(String), what misses the point of type safety.
Most helpful comment
this is it, all API now is based on
Qualifierinstead of String. Check beta-3