Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
skywalkerdude opened this issue Feb 10, 2025 · 0 comments
Open

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

skywalkerdude opened this issue Feb 10, 2025 · 0 comments
Assignees

Comments

@skywalkerdude
Copy link

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 {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants