Search code examples
javaandroiddependency-injectiondagger-2dagger

error: [Dagger/MissingBinding] when trying building the project


I have a service class and I want to provide it via Dagger. But I get this error below:

error: [Dagger/MissingBinding] service.KeyStoreService cannot be provided without an @Inject constructor or an @Provides-annotated method. service.KeyStoreService is provided at di.component.ApplicationComponent.getKeyStoreService()

Here is my component class:

@ApplicationScope
@Component(modules = {ApplicationContextModule.class, KeyStoreModule.class})
public interface ApplicationComponent {

    @ApplicationContext
    Context getApplicationContext();

    KeyStoreService getKeyStoreService();

}

Here is my KeyStoreModule:

@Module(includes = {ApplicationContextModule.class})
public class KeyStoreModule {

    @Provides
    @ApplicationScope
    KeyStoreServiceInterface getKeyStoreService(@ApplicationScope Context context){
        File file = new File(context.getFilesDir(), "keystore/keystore");
        return new KeyStoreService(file);
    }
}

KeyStoreService implements KeyStoreServiceInterface.

Here is how I start Dagger2:

public class MyApplication extends Application {

    private ApplicationComponent applicationComponent;

    @Override
    public void onCreate() {
        super.onCreate();

        applicationComponent = DaggerApplicationComponent.builder()
                .applicationContextModule(new ApplicationContextModule(this))
                .build();

    }

}

Anyone see where it could have gone wrong? I looked at similar questions on Stackoverflow but did not find anything that helped me.


Solution

  • Here is a thing: Dagger provides instances based on specific type. Here are a couple of ways to deal with this problem

    • Change the return type of getKeyStoreService method from KeyStoreServiceInterface to KeyStoreService in KeyStoreModule
    • Change the return type of getKeyStoreService method from KeyStoreService to KeyStoreServiceInterface in ApplicationComponent
    • Create an abstract method with @Binds annotation which will receive KeyStoreService and which return type will be KeyStoreServiceInterface (in order to do this the whole module should be abstract - so it is possible to either create separate abstract module with @Binds annotations or to make KeyStoreModule abstract and modify getKeyStoreService method to be static)
    • Again, using @Binds annotation to map KeyStoreService instance to the provided KeyStoreServiceInterface, but applying @Inject annotation on KeyStoreService constructor and provide keystore File through Dagger
    • Not using @Binds annotation, but applying @Inject annotation on KeyStoreService constructor and provide keystore File through Dagger