You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Dagger注入同类型对象?解决重复绑定报错

解决Dagger同类型对象重复绑定问题

这个问题很典型——当Dagger遇到同一个类型被多次绑定时,它没办法自动判断你需要注入哪个实例,所以才抛出了重复绑定的错误。解决的核心思路是用**限定符(Qualifier)**给不同用途的实例打上标记,让Dagger能精准区分它们。下面是一步步的解决方案:

1. 创建自定义限定符注解

首先,我们需要定义两个限定符,用来标记「API类型的统计仓库」和「缓存类型的统计仓库」,以及对应的Interactor实例:

import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

// 标记API相关的统计实例
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface StatisticApi {
}

// 标记缓存相关的统计实例
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface StatisticCache {
}

2. 修改WidgetModule,给绑定添加限定符

我们需要给重复类型的绑定分别加上对应的限定符,同时提供两个不同的WidgetStatisticInteractor实例(分别依赖API仓库和缓存仓库):

@Module
public abstract class WidgetModule {

    @Binds
    abstract WidgetPresenter widgetPresenter(WidgetPresenterImpl presenter);

    @Binds
    abstract WidgetSettingInteractor widgetSettingInteractor(WidgetSettingInteractorImpl settingInteractor);

    @Binds
    abstract WidgetRepository widgetSettingRepository(WidgetRepositoryImpl widgetRepository);

    // 给API类型的仓库绑定添加限定符
    @StatisticApi
    @Binds
    abstract WidgetStatisticRepository widgetStatisticApiRepository(WidgetStatisticApiRepositoryImpl apiRepository);

    // 给缓存类型的仓库绑定添加限定符
    @StatisticCache
    @Binds
    abstract WidgetStatisticRepository widgetStatisticCacheRepository(WidgetStatisticCacheRepositoryImpl cacheRepository);

    // 提供API类型的Interactor,注入带@StatisticApi标记的仓库
    @StatisticApi
    @Provides
    static WidgetStatisticInteractor provideStatisticApiInteractor(
            @StatisticApi WidgetStatisticRepository repository) {
        return new WidgetStatisticInteractorImpl(repository);
    }

    // 提供缓存类型的Interactor,注入带@StatisticCache标记的仓库
    @StatisticCache
    @Provides
    static WidgetStatisticInteractor provideStatisticCacheInteractor(
            @StatisticCache WidgetStatisticRepository repository) {
        return new WidgetStatisticInteractorImpl(repository);
    }
}

如果你的WidgetStatisticInteractorImpl已经添加了@Inject构造方法,也可以用@Binds替代@Provides,但需要在Interactor的构造里给仓库参数加上对应限定符。

3. 修改Presenter构造方法,添加限定符标记参数

最后,在WidgetPresenterImpl的构造方法里,给两个WidgetStatisticInteractor参数加上对应的限定符,让Dagger知道哪个参数对应哪个实例:

public class WidgetPresenterImpl implements WidgetPresenter {

    private final WidgetSettingInteractor mStateInteractor;
    private final WidgetStatisticInteractor mStatisticApiInteractor;
    private final WidgetStatisticInteractor mStatisticCacheInteractor;
    private final Context mContext;

    @Inject
    public WidgetPresenterImpl(
            WidgetSettingInteractor stateInteractor,
            @StatisticApi WidgetStatisticInteractor statisticApiInteractor,
            @StatisticCache WidgetStatisticInteractor statisticCacheInteractor,
            Context context) {
        mStateInteractor = stateInteractor;
        mStatisticApiInteractor = statisticApiInteractor;
        mStatisticCacheInteractor = statisticCacheInteractor;
        mContext = context;
    }

    // 其他业务方法...
}

额外注意

确保你的Dagger Component已经包含了这个WidgetModule,并且Context可以被Dagger正确提供(比如在Android中,你可以通过@BindsInstance在Component构建时注入Context)。

这样修改后,Dagger就能精准区分同类型的不同实例,解决重复绑定的编译错误了。

内容的提问来源于stack exchange,提问作者user1854307

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:59:55