How to provide objects of the same type? Dagger2
Asked Answered
P

2

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?

Purgation answered 6/11, 2016 at 8:12 Comment(0)
K
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/

Karlise answered 6/11, 2016 at 8:30 Comment(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.Dissoluble
M
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

Maffa answered 9/3, 2020 at 22:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.