如何提供相同类型的对象? Dagger2

时间:2016-11-06 08:12:32

标签: java android dagger-2

我是Dagger2的新手并尝试构建此类示例,以了解它是如何工作的。

有我的示例代码:

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;
}
}

您可以在MainActivity我注入Integer

的示例中看到
@Inject
protected Integer valueInt;

我也希望使用int为此方法provideApiInterface(int i)提供值作为参数。

最终我得到了这样的错误

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()

我做错了什么?

我应该如何正确地提供这个论点以避免这种错误?

2 个答案:

答案 0 :(得分:6)

您需要使用qualifier annotations

@Module
class ModelModule {

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

@Module
class AnotherModule {

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

并在注射依赖时使用此限定符

@Inject
protected ApiInterface apiInterface;

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

希望它有所帮助! 另请查看官方文档 - http://google.github.io/dagger/

答案 1 :(得分:0)

Kotlin 的示例,该示例使用@Name批注提供2个相同类类型的实例(也适用于基本类型)。


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)
}

场注入:

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

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

在调用inject()(例如活动的onCreate()或任何地方)后调用变量。


对于那些对Prefs类的外观感到好奇的人:stackoverflow.com