4

I am new at Dagger2 and tried to build such sample to understood how does it work.

There is my sample code :

MainActivity

public class MainActivity extends AppCompatActivity {

@Inject
protected ApiInterface apiInterface;

@Inject
protected Integer valueInt;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    App.getComponent().inject(this);
}

public void testButton(View view) {
    if (apiInterface == null || valueInt == null) {
        Log.e("TAG", "apiInterface == null");
    } else {
        Log.e("TAG", "apiInterface != null : " + apiInterface.value +  " : " + valueInt);
    }
 }
 }

Component

@Singleton
@Component(modules = {ModelModule.class, AnotherModule.class})
interface AppComponent {

void inject(MainActivity mainActivity);
}

Module

@Module
class ModelModule {

@Provides
int provideInt() {
    return 1;
}

@Provides
ApiInterface provideApiInterface(int i) {
    return ApiModule.getApiInterface(i);
}
}

Module

@Module
class AnotherModule {
@Provides
Integer getInt(){
    return 3;
}
}

as you can see in my sample in MainActivity i inject Integer

@Inject
protected Integer valueInt;

and also i want to use int to provide value as argument for this method provideApiInterface(int i).

And eventually i get such error

Error:(11, 10) error: java.lang.Integer is bound multiple times:
@Provides int com.krokosha.aleksey.daggertwo.ModelModule.provideInt()
@Provides Integer com.krokosha.aleksey.daggertwo.AnotherModule.getInt()

What am i doing wrong?

How am i supposed to provide this argument in proper way to avoid such error?

Maksim Ostrovidov
  • 10,720
  • 8
  • 42
  • 57
Sirop4ik
  • 4,543
  • 2
  • 54
  • 121

2 Answers2

7

You need to use qualifier annotations

@Module
class ModelModule {

    @Provides 
    @Named("FirstInt")
    int provideInt() {
        return 1;
    }
}

@Module
class AnotherModule {

    @Provides 
    @Named("SecondInt")
    int provideInt() {
        return 1;
    }
}

and use this qualifiers when injecting dependecies

@Inject
protected ApiInterface apiInterface;

@Inject 
@Named("FirstInt") //or whatever you need
protected int valueInt;

Hope it helps! Also check official docs - http://google.github.io/dagger/

gk5885
  • 3,742
  • 21
  • 16
Maksim Ostrovidov
  • 10,720
  • 8
  • 42
  • 57
  • 1
    A few notes: (1) It's good practice to _always_ use qualifiers for "common" types like primitives or types in `java.*` (2) Dagger will autobox and unbox. Prefer `int` over `Integer`. (3) `@Named` uses strings, which are subject to typos and don't survive refactoring particularly well. Prefer custom qualifiers in most cases. – gk5885 Nov 06 '16 at 18:03
0

Kotlin example of providing 2 instances of the same class type (works the same with primitive types, too) using the @Name annotation.


PrefsModule.kt

@Module
object PrefsModule {

    private const val packageName = "com.example.app"
    const val ENCRYPTED_PREFS = "$packageName.ENCRYPTED_PREFS"
    const val PREFS = "$packageName.PREFS"

    @Singleton
    @Provides
    @Named(ENCRYPTED_PREFS)
    @JvmStatic
    fun provideEncryptedSharedPreferences(application: Application): Prefs =
        Prefs(
            ENCRYPTED_PREFS,
            application.applicationContext,
            MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
        )

    @Singleton
    @Provides
    @Named(PREFS)
    @JvmStatic
    fun provideUnencryptedSharedPreferences(application: Application): Prefs =
        Prefs(PREFS, application.applicationContext)
}

Field Injection:

@Inject
@Named(PrefsModule.ENCRYPTED_PREFS)
lateinit var ePrefs: Prefs

@Inject
@Named(PrefsModule.PREFS)
lateinit var prefs: Prefs

Call the variables after you call inject() in say, your Activity's onCreate() or where ever.


For those curious about what the Prefs class looks like: stackoverflow.com

05nelsonm
  • 311
  • 3
  • 5