Closed mawenge closed 8 years ago
That method is executed by Dagger2 using a type of injection known as method injection. Currently, dagger supports three different types of injections:
This type of injection is performed when we have the @inject
annotation in a field, i.e: @Inject TasksPresenter mTasksPresenter;
. This is commonly used when our project requirements don't make us easy to use the constructor for injecting dependencies (activities, fragments on android for instance).
This approach uses the constructor for injecting dependencies, this is the old definition of dependency injection. When Dagger2 finds a constructor tagged with the @inject
annotation, it tries to create its dependencies based on another @inject
annotations around the constructors, or modules who create these dependencies.
@Inject
TasksPresenter(TasksRepository tasksRepository, TasksContract.View tasksView) {
mTasksRepository = tasksRepository;
mTasksView = tasksView;
}
This is the answer to your question, this final approach it uses methods annotated with the @inject
annotation to injects all its parameters with dependencies of the graph. The use of this injection is useful for receiving an instance of the class where it lives, since is called right after its constructor (when an instance is created), in that way we are able to pass a reference of the created presenter to the view. That's an elegant and a nice way to inject presenters into views in a model-view-presenter pattern.
/**
* Method injection is used here to safely reference {@code this} after the object is created.
* For more information, see Java Concurrency in Practice.
*/
@Inject
void setupListeners() {
mTasksView.setPresenter(this);
}
@saulmm thank you for this great explanation.
@saulmm thanks for your reply, and I also find that for a class, only with constructor injection will make the @inject method execute after constructor. if the PresenterImpl was instantiated by using a @Provide method in a module, like this
`@Provide
void providePresenter(TasksRepository tasksRepository, TasksContract.View tasksView) {
return new TasksPresenter(tasksRepository, tasksView);
}`
not @inject for constructor,
@Inject TasksPresenter(TasksRepository tasksRepository, TasksContract.View tasksView) { mTasksRepository = tasksRepository; mTasksView = tasksView; }
in this case ,setupListeners() will not execute,.
Am I right?
Yes I think so, the method injection will be performed by the MemberInjector class which understands that if you are able to create your instances via @Provide
you don't need a method injection.
/**
* Injects dependencies into the fields and methods of {@code instance}. Ignores the presence or
* absence of an injectable constructor.
*
* <p>Whenever the object graph creates an instance, it performs this injection automatically
* (after first performing constructor injection), so if you're able to let the object graph
* create all your objects for you, you'll never need to use this method.
*
* @param instance into which members are to be injected
* @throws NullPointerException if {@code instance} is {@code null}
*/
Sorry for the late response @mawenge
Closing this one, feel free to open a new issue if you have further questions.
in mvp dagger example, the presenter object was injected in activity, and in presenterImpl, there is a method "setupListeners"
@Inject void setupListeners() { mStatisticsView.setPresenter(this); }
the method make the View have reference of presenter, and this is a @Inject method.
I don't know when does this method execute and by who?