Dagger 2 component inheritance and errors

2.5k views Asked by At

I'm trying to create the following scenario:

public interface DaggerInjectionFactory {
    void inject(MyActivity myActivity);
}

@Singleton
@Component(modules = {RestModule.class})
public interface MyRestComponent extends DaggerInjectionFactory {
    RestClient provideRestClient();
}

@Singleton
@Component(modules = {PreferencesModule.class})
public interface MyPreferencesComponent extends DaggerInjectionFactory {
    SharedPreferences provideSharedPreferences();       
}

The dagger compiler gives me the following error as a response:

error: RestClient cannot be provided without an @Provides- or @Produces-annotated method.

The RestModule contains a @Provides @Singleton RestClient provideRestClient() method and it is also worth noting that when I remove the extends DaggerInjectionFactory from the MyPreferencesComponent the dagger compiler has no issue in generating the component builders.

What I'm trying to do is create an interface with all the injectable classes, in which I want to use the @Inject annotation, and implement them in 'all' of my components so I don't have to add the void inject(MyActivity myActivity); to all of my components.

Because I'm new to the framework I have no idea what the correct terminology is and therefore have no real clue as to what I need to search for.

So my questions are: is it possible to create such a structure, to define an interface which automatically adds all the void inject() methods to 'all' of my components? and if so, how can it be done?

-- Edit -- The expected usage would be something like:

public MyActivity extends Activity {
    private RestClient restClient;
    private SharedPreferences sharedPreferences;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        MyRestComponent.Instance.build().inject(this);
        MyPreferencesComponent.Instance.build().inject(this);
    }

    @Inject
    public void setRestClient(RestClient restClient){
        this.restClient = restClient;
    }

    @Inject
    public void setSharedPreferences(SharedPreferences sharedPreferences){
        this.sharedPreferences = sharedPreferences;
    }
}
1

There are 1 answers

0
Piotr Mądry On

You don't need to create components for each module. You can just add more modules to component and as provide all classes in on this one interface.

@Singleton
@Component(
    modules = {RestModule.class, PreferencesModule.class}
)
    public interface AppComponent {

    void inject(MainApplication app)
    void inject(MainActivity activity);
}

if you are asking for inject component to all activites/fragment/MainApplication there is no method for this. You have to specify which of these above will get dependency injection.