@Binds can be perfectly equivalent to a @Provides-annotated method like this:
@Provides
public HomePresenter provideHomePresenter() {
return new HomePresenterImp();
}
...though you'd probably prefer a variant that takes HomePresenterImp as a method parameter, which lets Dagger instantiate HomePresenterImp (assuming it has an @Inject constructor) including passing any dependencies it needs. You can also make this static
, so Dagger doesn't need to instantiate your Module instance to call it.
@Provides
public static HomePresenter provideHomePresenter(HomePresenterImp presenter) {
return presenter;
}
So why would you choose @Binds
instead? Dagger has a FAQ about it, but it boils down do these reasons:
- @Binds is (slightly) more compact: You can skip the implementation.
- @Binds works in interfaces and abstract classes, which are strictly required for Dagger features like @BindsOptionalOf and @ContributesAndroidInjector.
- @Binds helps your code stay efficient. @Provides methods can be instance methods, which require Dagger to instantiate your Module in order to call them. Making your @Provides method
static
will also accomplish this, but your @Provides method will still compile if you forget the static
. @Binds methods will not.
- @Binds prevents Dagger from having to codegen and keep a separate Factory/Provider for the object, since Java doesn't give Dagger access to know that the implementation is as simple as it is. In your case, Dagger can cast the
Provider<HomePresenterImp>
to a Provider<HomePresenter>
and only keep one, rather than keeping one for HomePresenter that does nothing but call the one for HomePresenterImp.
Thus, the entire thing would be well-represented as:
@Binds abstract HomePresenter bindHomePresenter(HomePresenterImp presenter);
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…