mdelolmo
mdelolmo

Reputation: 6457

Dagger 2: Gradle module dependency with implementation in another module

I am trying to set up a project in which I have two modules common-lib and app.

The lib module has its own Dagger component and modules, and it's supposed to be flavor agnostic.

Now, part of it depends on flavor specific resource values declared in the module app, so I tried abstracting the component through an interface and override its implementation in the module app.

Dagger module declare in common-lib gradle module, satisfying dependencies with NoOp implementations.

    @Module
public class NetworkConfigModule {
    @Provides
    @Singleton
    HeaderParams providesHeaderParams(NoOpHeaderParams noOpHeaderParams){
        return noOpHeaderParams;
    }

    @Provides
    @Singleton
    AppHostsProvider providesAppHostsProvider(NoOpAppHostsProvider noOpAppHostsProvider){
        return noOpAppHostsProvider;
    }
}

Dagger module declare in app gradle module, satisfying dependencies with the actual implementation.

@Module
public class NetworkConfigModule {

    @Provides
    @ApplicationScope
    HeaderParams providesHeaderParams(KaufdaHeaderParams kaufdaHeaderParams){
        return kaufdaHeaderParams;
    }

    @Provides
    @ApplicationScope
    AppHostsProvider providesAppHostsProvider(KaufdaAppHostsProvider implementation){
        return implementation;
    }
}

This doesn't work, because Dagger just doesn't override the Module class, but that's somehow expected.

My question is, how I can set up my Dagger modules so I can use HeaderParams and AppHostsProvider interfaces in common-lib, but I inject their implementations in app.

Upvotes: 0

Views: 1406

Answers (1)

David Medenjak
David Medenjak

Reputation: 34542

The easiest way would be to just handle the component creation in your app.

In your app you know the actual modules and classes that you want to use. If you create the component there, you can just add the right module to the component, inject your common-lib classes and be done.


If you don't want to handle the injection in your app, you would need to define an interface, e.g.

interface NetworkComponentHolder {
    NetworkComponent getNetworkComponent();
}

which then in turn you could implement with your Application in app. Again, you would have to create the component and modules in your app, but then from your module you can call

((NetworkComponentHolder) getApplication()).getNetworkComponent().inject(this);

This would be the 2 possibilities without using reflection.

Upvotes: 3

Related Questions