Dagger2中@Binds与@Provides批注的用例是什么

j2e*_*nue 9 android dagger-2

我不确定Dagger2的@Bind注释的用途

根据我在网上阅读的内容,即时通讯仍然不清楚,但这是一个示例:

@Module
public abstract class HomeModule {

  @Binds
  public abstract HomePresenter bindHomePresenter(HomePresenterImp   
    homePresenterImp);
}
Run Code Online (Sandbox Code Playgroud)

并且类定义如下所示:

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

public class HomePresenterImp implements HomePresenter {

    public HomePresenterImp(){
    }  

    @Override
    public Observable<List<User>> loadUsers(){
        //Return user list observable
    }
}
Run Code Online (Sandbox Code Playgroud)

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

@Provides
public HomePresenter provideHomePresenter() {
    return new HomePresenterImp();
}
Run Code Online (Sandbox Code Playgroud)

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

Jef*_*ica 11

@Binds可以完全等同于@Provides注释的方法,如下所示:

@Provides
public HomePresenter provideHomePresenter() {
    return new HomePresenterImp();
}
Run Code Online (Sandbox Code Playgroud)

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

@Provides
public static HomePresenter provideHomePresenter(HomePresenterImp presenter) {
    return presenter;
}
Run Code Online (Sandbox Code Playgroud)

那为什么要选择@Binds呢?Dagger对此有一个常见问题解答,但归结为以下原因:

  • @Binds(略)更紧凑:您可以跳过实现。
  • @Binds在接口和抽象类中工作,而Dagger功能(例如@BindsOptionalOf和@ContributesAndroidInjector)则严格要求使用@Binds。
  • @Binds帮助您的代码保持高效。@Provides方法可以是实例方法,需要Dagger实例化您的Module才能调用它们。设置@Provides方法static也可以完成此操作,但是如果您忘记了@Provides方法,仍然可以编译static。@Binds方法不会。
  • @Binds防止Dagger进行代码生成并为该对象保留单独的Factory / Provider,因为Java不允许Dagger访问其实现是多么简单。在您的情况下,Dagger可以将Provider<HomePresenterImp>a Provider<HomePresenter>强制转换为a,并且仅保留一个,而不是为HomePresenter保留一个,而只为HomePresenterImp调用一个。

因此,整个事情可以很好地表示为:

@Binds abstract HomePresenter bindHomePresenter(HomePresenterImp presenter);
Run Code Online (Sandbox Code Playgroud)


小智 9

感谢这个来源: https ://www.valueof.io/blog/inject-provides-binds-dependency-dagger-hilt

\n

@绑定:

\n
    \n
  • 单个参数
  • \n
  • 更少的代码
  • \n
\n

不过,使用@Binds的好处是减少了生成的代码量(比如Module Factory类)在此输入图像描述s)。生成的代码更少意味着 Kapt 插件要做的工作更少,这可以加快大型项目的构建时间。

\n

@Binds 是一个非常专业的注释,尽管 \xe2\x80\x94it\xe2\x80\x99s 用于将接口映射到实现。它只能采用单个参数,并且返回类型是给定参数对象实现的接口。

\n

如果您要绑定的实现采用构造函数参数,则可以使用 @Inject 和 @Binds 的组合,如下例所示:

\n


Sam*_*net 5

这是一个需要Bind注释的具体情况,假设您有一个BaseActivityModule包含在提供活动视图模型的所有活动模块中的注释。

@Module
object BaseActivityModule {
    @Provides
    @ActivityScope
    @ActivityContext
    @JvmStatic
    fun provideViewModelProvider(
        activity: AppCompatActivity,
        viewModelFactory: ViewModelProvider.Factory
    ): ViewModelProvider = ViewModelProviders.of(activity, viewModelFactory)
}
Run Code Online (Sandbox Code Playgroud)

在这里您可以看到我们需要提供 anAppCompatActivity和 a ViewModelProvider.Factory。您无法提供AppCompatActivity注释,Provide因为活动是由 android 创建的。

我们假设您的具体示例ActivityModuleMainActivityModule提供MainActivity类,因为您创建了 MainActivity 子组件,或者您曾经ContributesAndroidInjector自动创建子组件(但这是另一个话题)。

所以我们有我们的MainActivityModule提供MainActivity和我们的MainActivityModule包括我们BaseActivityModule需要的AppCompatActivity。因此,神奇之处在于Bind,让我们告诉 Dagger,当您需要时,AppCompatActivity您可以使用我们的MainActivity.

@Module(includes = [BaseActivityModule::class])
abstract class MainActivityModule {
    @Binds
    @ActivityScope
    abstract fun bindActivity(activity: MainActivity): AppCompatActivity
}
Run Code Online (Sandbox Code Playgroud)

您可以在此处查看我的项目模板的更多内容