Skip to content

[Regression] AutoFactory 1.1.0 no longer propagates @Qualifier #1884

@skywalkerdude

Description

@skywalkerdude

Upgrading to AutoFactory 1.1.0 seems to cause objects @Provided with @Qualifiers to no longer work. It appears that the qualifier is not propagated to the generated factory class, whereas with version 1.0.1, it was.

Long story short, the AutoFactory used to propagate the qualifier to the generated factory class:

  @Inject
  public MyClassFactory(@MyQualifier Provider<Integer> valueProvider) {
    ...
  }

Now, the qualifier is no longer propagated, causing dagger to be unable to find the @Provides annotation:
error: [Dagger/MissingBinding] java.lang.Integer cannot be provided without an @Inject constructor or an @Provides-annotated method.

  @Inject
  public MyClassFactory(Provider<Integer> valueProvider) {
    ...
  }

To fully reproduce the issue, here is a link to a sample app, but if that doesn't work, I'll also paste the applicable code below. Please let me know if you have any questions, and I appreciate someone looking into it!

MainActivity.java:

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

import javax.inject.Inject;

public class MainActivity extends Activity {

    @Inject MyClassFactory myClassFactory;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AppComponent component =
            DaggerAppComponent.builder()
                              .myModule(new MyModule())
                              .build();
        component.inject(this);


        TextView textView = findViewById(R.id.text_view); // Make sure you have this TextView in your layout

        // Using generated factory to create an instance with a non-injected constructor
        MyClass myClass = myClassFactory.create("Hello from AutoFactory!");
        System.out.println(myClass.getMessage() + " Value: " + myClass.getValue());
        textView.setText(myClass.getMessage() + " Value: " + myClass.getValue());
    }

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

AppComponent.java:

import dagger.Component;

@Component(modules = {MyModule.class})
public interface AppComponent {
    void inject(MainActivity activity);
}

MyClass.java:

import androidx.annotation.NonNull;

import com.google.auto.factory.AutoFactory;
import com.google.auto.factory.Provided;

import javax.inject.Inject;

@AutoFactory
public class MyClass {

    private final String message;
    private final int value;

    @Inject
    public MyClass(@NonNull String message,
            @Provided @MyQualifier int value) {
        this.message = message;
        this.value = value;
    }

    public String getMessage() {
        return message;
    }

    public int getValue() {
        return value;
    }
}

MyModule.java:

import dagger.Module;
import dagger.Provides;

@Module
public class MyModule {

    @Provides
    @MyQualifier
    int provideValue() {
        return 42;
    }
}

MyQualifier.java:

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.inject.Qualifier;

/**
 * Qualifier to indicate that the object is the context of the favorites screen.
 */
@Qualifier
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
public @interface MyQualifier {
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions