JakeWharton / dagger-reflect

A reflection-based implementation of the Dagger dependency injection library for fast IDE builds.
Apache License 2.0
655 stars 44 forks source link

Module with generic fails to find the target #135

Open kokeroulis opened 5 years ago

kokeroulis commented 5 years ago

When we have a module with a generic type then dagger-reflect fails to resolve this dependency. For example given that we have the following module

@Module
public abstract class BaseActivityBindingModule<T extends Activity> {

    @Binds
    public abstract Activity bindActivity(T activity);
}

We will receive the following exception

java.lang.IllegalStateException: Missing binding for T
 * Requested: android.app.Activity
     from @Binds[com.example.BaseActivityBindingModule.bindActivity(…)]
 * Requested: T
     which was not found.
    at dagger.reflect.Linker.failure(Linker.java:52)
    at dagger.reflect.Linker.get(Linker.java:22)
    at dagger.reflect.UnlinkedBindsBinding.link(UnlinkedBindsBinding.java:26)
    at dagger.reflect.Linker.link(Linker.java:35)
    at dagger.reflect.Scope.link(Scope.java:143)
    at dagger.reflect.Scope.findExistingBinding(Scope.java:101)
    at dagger.reflect.Scope.findBinding(Scope.java:69)
    at dagger.reflect.Scope.getBinding(Scope.java:39)
    at dagger.reflect.ReflectiveMembersInjector.create(ReflectiveMembersInjector.java:61)
    at dagger.reflect.UnlinkedJustInTimeBinding.link(UnlinkedJustInTimeBinding.java:41)
    at dagger.reflect.Linker.link(Linker.java:35)
    at dagger.reflect.Scope.link(Scope.java:143)
    at dagger.reflect.Scope.putJitBinding(Scope.java:136)
    at dagger.reflect.Scope.findBinding(Scope.java:76)
    at dagger.reflect.Scope.getBinding(Scope.java:39)
    at dagger.reflect.ReflectiveMembersInjector.create(ReflectiveMembersInjector.java:61)
    at dagger.reflect.ReflectiveAndroidInjector$Factory.create(ReflectiveAndroidInjector.java:50)
    at dagger.android.DispatchingAndroidInjector.maybeInject(DispatchingAndroidInjector.java:111)
    at dagger.android.DispatchingAndroidInjector.inject(DispatchingAndroidInjector.java:134)
    at dagger.android.AndroidInjection.inject(AndroidInjection.java:63)
    at com.example.ExampleActivity.onCreate(ExampleActivity.java:25)

We can reproduce this by running ./gradlew :integration-tests:android:testReflectDebugUnitTest

For the above scenario I have created a sample project which is reproducing this issue, you can find the full source code here, the branch name is atsiap/module_with_generic.

Dagger's original code generation works properly and it can be verified by running ./gradlew :integration-tests:android:testCodegenDebugUnitTest.

JakeWharton commented 5 years ago

A bunch of the Dagger functional tests cover this and are currently muted. Hope to get to it eventually, but it's probably non-trivial.

catellie commented 4 years ago

In my experience, this is the only major blocker for using dagger-reflect in non-trivial projects.