【问题标题】:How to provide objects of the same type? Dagger2如何提供相同类型的对象?匕首2
【发布时间】:2017-03-19 17:44:04
【问题描述】:

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

我做错了什么?

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

【问题讨论】:

    标签: java android dagger-2


    【解决方案1】:

    你需要使用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) 最好总是对“常见”类型使用限定符,例如 java.* 中的基元或类型 (2) Dagger 将自动装箱和拆箱.首选int 而不是Integer。 (3) @Named 使用字符串,这些字符串容易出现拼写错误,并且无法很好地通过重构。在大多数情况下,首选自定义限定符。
    【解决方案2】:

    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() 之后调用变量,比如你的Activity 的onCreate() 或任何地方。


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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-13
      • 2020-10-02
      • 2018-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      相关资源
      最近更新 更多