Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger 2 - Constructor injection - Scope

I'm using Dagger 2 with simple MVP pattern. I have a @PerApp and @PerActivity scopes. I'm injecting presenters dependencies using constructor injection, which makes those presenters "injectable" (I don't need to write provides methods in activity module). Code fragments:

PerApp:

// AppComponent
@PerApp
@Component(modules = {AppModule.class, DataModule.class, NetworkModule.class})
public interface AppComponent {
    LoginComponent plus(LoginModule loginModule);

    MainComponent plus(MainModule mainModule);
}

// Example @PerApp module
@Module
public class NetworkModule {

    @Provides
    @PerApp
    Retrofit providesRetrofit(){
         ...
    }
}

PerActivity:

// LoginModule
@Module
public class LoginModule {
    private final LoginActivity mLoginActivity;

    public LoginModule(LoginActivity loginActivity) {
        mLoginActivity = loginActivity;
    }

    @Provides
    @PerActivity
    Context providesContext() {
        return mLoginActivity;
    }
}

// LoginComponent
@PerActivity
@Subcomponent(
        modules = LoginModule.class
)
public interface LoginComponent {
    void inject(LoginActivity loginActivity);
}

Activity:

public class LoginActivity {
    @Inject LoginPresenter mPresenter;
}

Presenter:

public class LoginPresenter {

    @Inject
    public LoginPresenter(Retrofit retrofit) {
        ...
    }
}

It's working great. My question is: What will be the scope of provided LoginPresenter? Is it gonna be the same as LoginActivity? Should I annotate the presenter's constructor with @PerActivity or something?

like image 877
rafakob Avatar asked Apr 06 '16 09:04

rafakob


1 Answers

I've ran some tests to check by myself how exactly scoping works with constructor injection and here are my results.

1) Inject LoginPresenter into LoginActivity:

LoginComponent - @PerActivity scope (code is exactly the same as in my first post).

I've tried to inject presenter into 2 variables:

public class LoginActivity {
    @Inject LoginPresenter A;
    @Inject LoginPresenter B;
}

LoginPresenter annotated with:

  • nothing - A and B are different
  • @PerActivity - A and B are the same
  • @PerApp - A and B are the same

2) Inject LoginPresenter into LoginActivity and MainActivity:

LoginComponent, MainComponent - @PerActivity scope (code is exactly the same as in my first post).

I've tried to inject presenter into 2 different activities:

public class LoginActivity {
    @Inject LoginPresenter A;
}

public class MainActivity {
    @Inject LoginPresenter B;
}

LoginPresenter annotated with:

  • nothing - A and B are different
  • @PerActivity - A and B are different
  • @PerApp - A and B are the same
like image 107
rafakob Avatar answered Sep 21 '22 15:09

rafakob