evant / kotlin-inject

Dependency injection lib for kotlin
Apache License 2.0
1.29k stars 60 forks source link

Annotation support for exposing a supertype to the graph #415

Closed ursusursus closed 4 months ago

ursusursus commented 4 months ago

In dagger + anvil I write a lot of

@CustomerScope
@ContributesBinding(CustomerScope::class)
@Inject
class CustomerRepositoryImpl(
    ...
) : CustomerRepository

CustomerScope literal is there twice for no obvious reason & just adds noise.

Can we do better?

This is very common pattern, I'd best like for it to be a parameter of @Inject(bindSupertype = true) or something like that

evant commented 4 months ago

This feels like a duplicate of other anvil-like feature requests so I'm going to close it in favor of https://github.com/evant/kotlin-inject/issues/212, let me know if there's anything I'm missing!

ursusursus commented 4 months ago

Well...imo Anvil has the annotation because the rebinding pattern is ugly with vanilla dagger.

With kotlin-inject being new take on dagger, I feel like this should be in the base library.

"Anvil"-like extension should be solution for multi-module setups.

evant commented 4 months ago

Say you are injecting CustomerRepository somewhere, we need to find what the actual implementation is. The way this happens today is for the component to have the line

@Provides
fun CustomerRepositoryImpl.bind(): CustomerRepository = this

Regardless on what the exact annotation api looks like, it would have to generate the above line so the implementation can be found, which is the same thing anvil does. It's the same level of complexity to implement. The issue I linked already covers some ground on how this might be done.

The only other way to accomplish this is to scan every file in the project looking for the implementation and that's a non-starter.

ursusursus commented 4 months ago

Okay guess it depends on how you view anvil.

Firstly it was a solution for multi-module projects, so you don't have to add : MyModuleComponent to the final one, as that causes conflicts and doesn't scale + same for @Modules

Afterwards, they added features which "fix" dagger usability problems like @ContributesBinding/@ContributesMultibinding.

Personally I'd have liked to see the latter in the original library, as that pattern is present even in a single module library.

If the @Provides fun CustomerRepositoryImpl.bind(): CustomerRepository = this is the only syntax then sure - I was thinking sort of sinking it to @Inject level handling, so it becomes a first class citizen, but yea I cannot speak of to the implementation/internal issues of that all

Same like @Assisted used to be extension and now is native

evant commented 4 months ago

The core of the issue is that

Afterwards, they added features which "fix" dagger usability problems like @ContributesBinding/@ContributesMultibinding.

depends on

Firstly it was a solution for multi-module projects, so you don't have to add : MyModuleComponent to the final one

you need to have that component generation to add those annotations

ursusursus commented 4 months ago

Fair but that means anvil2 will be used in like 99% of cases of people using kotlin-inject. Is the anvil2 coming for sure? Last time I checked @vRallev only said he hopes to opensource it.