如何提供相同类型的对象?匕首2

How to provide objects of the same type? Dagger2

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

我做错了什么?

我应该如何以正确的方式提供此参数以避免此类错误?

您需要使用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/

Kotlin 使用 @Name 注释提供相同 class 类型的 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() 之后调用变量,比如你的 Activity 的 onCreate() 或任何地方。


对于那些想知道 Prefs class 是什么样子的人:whosebug.com