I'm trying to use a Model-View-Presenter pattern in my Android project. I am using the excellent RoboGuice project with AssistedInject to manage my dependencies. I am struggling with the style of creating instances of my presenters.
AssistedInject appears to require me to first inject a factory to create a presenter and then use that factory to create an instance of a presenter. Injection (appears) to only work at the class scope level; I cannot inject local variables. My methods do not need both a factory and a presenter; I only care about the factory long enough to generate a single presenter. I'd like to avoid keeping the mostly useless factory around.
More Detail
In my implementation of the pattern, I choose for each presenter and view to hold a reference to the other. A presenter must usually be passed one or more "Service" objects that are used to interact with the model. An Android Activity is an implementation of a (MVP) View. An Activity must be the composition root of any Android application. Therefore, each activity must instantiate a presenter, and that presenter needs a service as well as a reference to the view.
In general, presenters look like
public class GreatStuffPresenter {
private final SomeService service;
private final GreatStuffView view;
@Inject
public GreatStuffPresenter(SomeService service, @Assisted GreatStuffView view) {
this.service = service;
this.view = view;
bind();
}
public void bind() {
Record r = service.getSomeRecord();
view.setField(r.field);
}
}
and Activites look like
public class GreatStuffActivity extends RoboActivity {
@Inject private final GreatStuffPresenterFactory presenterFactory;
private GreatStuffPresenter presenter;
@Override
public void onCreate(...) {
super.onCreate(savedInstanceState);
setContentView(R.layout.create_update_record);
presenter = presenterFactory.create(this);
}
}
Now What?
I am dissatisfied that I must scope the presenterFactory
at the instance level; I only need it during onCreate()
. Am I missing some additional magic that RoboGuice could perform for me? If not, is there a better practice or pattern I should be using to avoid this unnecessary scoping?