I'm starting to use Dagger 2 in an application I'm developing but I have some questions about how Dagger 2 works.
I get the all the logic behind the @Provides methods and the @Inject annotation for initialising your dependencies, but the @Inject annotation to class constructors kind of bugs my mind.
For example:
Im my app, I have one module defined, the ContextModule, to retrieve the context of my application:
ContextModule.java
@Module
public class ContextModule {
private final Context context;
public ContextModule(Context context) {
this.context = context;
}
@Provides
public Context context() {
return this.context;
}
}
This module is used by my BaseActivityComponent:
BaseActivityComponent.java
@BaseActivityScope
@Component(modules = ContextModule.class)
public interface BaseActivityComponent {
void injectBaseActivity(BaseActivity baseActivity);
}
So far so good.. then I have an AuthController class, that depends on the context and I want to inject it in my BaseActivity. So in my AuthControllers.class I have something like:
public class AuthController {
private Context context;
@Inject
public AuthController(Context context) {
this.context = context;
}
public void auth() {
// DO STUFF WITH CONTEXT
}
}
And I inject it in my BaseActivity like:
public class BaseActivity extends AppCompatActivity {
@Inject
AuthController authController;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BaseActivityComponent component = DaggerBaseActivityComponent.builder()
.contextModule(new ContextModule(this))
.build();
component.injectBaseActivity(this);
authController.auth();
}
}
Now my question is, how does dagger knows that my AuthControllers is a dependency for BaseActivity? Just by declaring
@Inject
AuthController authController;
it's like the same thing as if I created a ControllerModule like:
@Module(includes = ContextModule.class)
public class ControllerModule {
@Provides
AuthController authController(Context context) {
return new AuthController(context);
}
}
And then in my BaseActivityComponent I would add my AuthController getter and change my dependency module to ControllersModule:
@BaseActivityScope
@Component(modules = ControllersModule.class)
public interface BaseActivityComponent {
void injectBaseActivity(BaseActivity baseActivity);
AuthController getAuthController();
}
When I call injectBaseActivity(this) it "tells" dagger that all @Inject annotations are dependencies of my class, and then it searchers my project for @Inject annotated constructors that matches that type?
I thought a good thing about Dagger 2 is that the Module files could be used as a "documentation" of my dependencies three. But if just add @Inject in all the constructors I have control of, couldn't it get a little confusing in the future, since you don't know what actually depends on what? (I mean, you know what depends on what, you just have to browse a lot of files to really find out)
Is there any best practices for when using @Inject annotations in constructors or when to add the @Provides method in Modules files? I get that using @Inject in constructor I don't need to change the constructor definition in my Module file, but is there any downside?
Thanks.