Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
571 views
in Technique[技术] by (71.8m points)

android - What is the use case for @Binds vs @Provides annotation in Dagger2

I am not certain on the purpose for Dagger2's @Bind annotation.

From what i have read online im still not clear but here is an example:

@Module
public abstract class HomeModule {

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

and the class definitions look like this:

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

public class HomePresenterImp implements HomePresenter {

    public HomePresenterImp(){
    }  

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

why would i need to use @Binds if i can just use provides annotation as follows:

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

what is the usecase for @Binds instead of @Provides ? if i use @Binds do i still need to declare it in my appcomponent (its an abstract class when i use @Binds)?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

@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);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...