google / google/auto

[Regression] AutoFactory 1.1.0 no longer propagates @Qualifier

Open
#1,884 0 comments 0 reactions 1 assignee Claimed by @eamonnmcmanus View on GitHub
Component: factory P2 Status: accepted type=defect
Dominant language
Java
Stars
10.6k
Forks
1.2k
Avg merge
6h 32m
Merged PRs (30d)
13

Description

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 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 valueProvider) {
...
}
```

To fully reproduce the issue, [here](https://drive.google.com/file/d/1HU2aYEJorXCZ8a4dOhTU19rNb7J2e6h0/view?usp=drive_link) 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`:
```

```

`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 {
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.