Koin: Add qualifiers

Created on 30 Nov 2018  路  8Comments  路  Source: InsertKoinIO/koin

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.

core accepted

Most helpful comment

this is it, all API now is based on Qualifier instead of String. Check beta-3

All 8 comments

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.

Was this page helpful?
0 / 5 - 0 ratings