首页 > 解决方案 > Dagger2中@Binds vs @Provides注解的用例是什么

问题描述

我不确定 Dagger2 的@Bind 注释的目的。

从我在网上阅读的内容来看,我仍然不清楚,但这里有一个例子:

@Module
public abstract class HomeModule {

  @Binds
  public abstract HomePresenter bindHomePresenter(HomePresenterImp   
    homePresenterImp);
}

并且类定义如下所示:

public interface HomePresenter {
    Observable<List<User>> loadUsers();
}

public class HomePresenterImp implements HomePresenter {

    public HomePresenterImp(){
    }  

    @Override
    public Observable<List<User>> loadUsers(){
        //Return user list observable
    }
}

如果我只能使用提供注释,为什么我需要使用@Binds,如下所示:

@Provides
public HomePresenter provideHomePresenter() {
    return new HomePresenterImp();
}

@Binds 而不是 @Provides 的用例是什么?如果我使用@Binds,我还需要在我的appcomponent 中声明它吗(当我使用@Binds 时它是一个抽象类)?

标签: androiddagger-2

解决方案


@Binds 可以完全等同于 @Provides-annotated 方法,如下所示:

@Provides
public HomePresenter provideHomePresenter() {
    return new HomePresenterImp();
}

...尽管您可能更喜欢将 HomePresenterImp 作为方法参数的变体,它允许 Dagger 实例化 HomePresenterImp(假设它有一个 @Inject 构造函数),包括传递它需要的任何依赖项。你也可以这样做static,所以 Dagger 不需要实例化你的 Module 实例来调用它。

@Provides
public static HomePresenter provideHomePresenter(HomePresenterImp presenter) {
    return presenter;
}

那你为什么会选择@Binds呢?Dagger 有一个关于它的常见问题解答,但归结为以下原因:

  • @Binds (稍微)更紧凑:您可以跳过实现。
  • @Binds 在接口和抽象类中工作,这对于 Dagger 功能(如 @BindsOptionalOf 和 @ContributesAndroidInjector)是严格要求的。
  • @Binds 帮助您的代码保持高效。@Provides 方法可以是实例方法,这需要 Dagger 实例化您的 Module 才能调用它们。使您的 @Provides 方法static也可以完成此操作,但是如果您忘记了static. @Binds 方法不会。
  • @Binds 可以防止 Dagger 必须进行代码生成并为对象保留一个单独的工厂/提供程序,因为 Java 没有让 Dagger 访问知道实现就这么简单。在您的情况下,Dagger 可以将其Provider<HomePresenterImp>转换为 aProvider<HomePresenter>并且只保留一个,而不是为 HomePresenter 保留一个,它只为 HomePresenterImp 调用一个。

因此,整个事情将被很好地表示为:

@Binds abstract HomePresenter bindHomePresenter(HomePresenterImp presenter);

推荐阅读