Be More Productive with Dagger2

Read Time 2 minutes

 

According to single responsibility and separation of concern concept no component of your application should Create  the new objects of other classes it needs. Those objects(Dependencies) should be created and  provided by someone else.

Dagger is (that someone else) a dependency injection framework for android and as of now, is the best amongst all.  If you don’t know about Dagger and how how use it. You might find this article Tasting Dagger 2 on Android and this video useful.

What I am going to explain is how you can be more productive using Dagger2. Consider this very basic Presenter for a login screen.

public class LoginPresenter extends BasePresenter {

 private static final String TAG = LoginPresenter.class.getSimpleName();

 public interface LoginView extends BaseView {
        void onLoginSuccess();
        void onLoginFailure(String errorMessage);
  }


 private LoginView mLoginView;
 private final LoginUsecase mLoginUsecase;
    
 @Inject
 public LoginPresenter(LoginUsecase mLoginUsecase) {
        this.mLoginUsecase = mLoginUsecase;
        
 }
 public void login(@NonNull String username, @NonNull String password) {

    if (username == null || password == null) {
        throw new IllegalArgumentException("invalid arguments: username and password required");
    }

    showLoading();
    mLoginUsecase.login(username, password);
 }
  . . . 
}

We have injected the LoginUsecase dependency via dagger using @inject notation. Suppose now that we want to save user settings received in response, in Shared Preference.  So lets modify our constructor:

public class LoginPresenter extends BasePresenter {

  private static final String TAG = LoginPresenter.class.getSimpleName();

  public interface LoginView extends BaseView {
        void onLoginSuccess();
        void onLoginFailure(String errorMessage);
  }

  private LoginView mLoginView;
  private final LoginUsecase mLoginUsecase;
  private final AppPreference appPreference;
 
  @Inject
  public LoginPresenter(LoginUsecase mLoginUsecase,AppPreference appPreference){
   this.mLoginUsecase = mLoginUsecase;
   this.appPreference= appPreference; 
  }

  public void login(@NonNull String username, @NonNull String password) {
    if (username == null || password == null) {
        throw new IllegalArgumentException("invalid arguments: username and password required");
    }
    showLoading();
    mLoginUsecase.login(username, password);
  }

  @Subscribe(threadMode = ThreadMode.MAIN)
  public void onLoginResult(LoginUsecaseImpl.EventLogin event) {

    hideLoading();
    if (event.exception != null) {
        Log.d(TAG, "login failure", event.exception);

    } else {
       appPreference.setUserCode(loginResponse.getUserCode());
       mLoginView.onLoginSuccess();
   }
 }  . . . 
}

As you can see if we were not using the Dagger we have to  modify the our code on the all the locations where this Presenter’s constructor is being called. But as we are using Dagger  we don’t need to do anything else other than defining the AppPreference dependency in our Dagger Module and Dagger  will take care the rest!

Now if on later development stages, you need ErrorMessageFactory for custom error messages you can just inject the ErrorMessageFactory via constructor and nothing else!

 

 

 

Leave a Comment

Your email address will not be published. Required fields are marked *