Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger with Android: How to inject context when using MVP?

While developing an Android application I stumbled on a problem. I just started using Dagger so I know some basic concepts but when using it outside the scopes of tutorials and their use cases things become less clear.

So to get to the point. In my application I'm using MVP as described in this blog post: http://antonioleiva.com/mvp-android/

So at first I was injecting the Interactor class (the one that handles the data) to the Presenter class and everything was ok. But then I implemented methods that use SQLite database, so now there was a need to use Context in my Interactor class.

I can't figure out how should I do this properly? My temporary fix was to exclude Dagger from my application and pass Context variable in constructor when creating Presenter class and then Interactor class inside presenter but I'd like to use Dagger.

So my current application looks somewhat like this.

MyActivity implements MyView {     
      MyPresenter p = new MyPresenter(this, getApplicationContext());
}

Constructor inside MyPresenter

MyPresenter(MyView view, Context context) {
      this.view = view;
      MyInteractor i = new MyInteractor(context);
}

And in constructor in MyInteractor I assign Context to a private variable.

I would only need to inject MyInteractor to MyPresenter, because this is the part of application that will need to be tested against different implementations. But if it would be also possible to inject MyPresenter to MyActivity, that would be great :)

I hope someone has some experience with what I'm trying to achieve :)

like image 741
Denis Vitez Avatar asked Apr 01 '15 09:04

Denis Vitez


1 Answers

In your class MyInteractor:

public class MyInteractor {

    @Inject
    public MyInteractor(Context context) {
       // Do your stuff...
    }
}

MyPresenter-class

public class MyPresenter {
    @Inject
    MyInteractor interactor;

    public MyPresenter(MyView view) {
        // Perform your injection. Depends on your dagger implementation, e.g.
        OBJECTGRAPH.inject(this)
    }
}

For injecting a Context you will need to write a module with a provides method:

@Module (injects = {MyPresenter.class})
public class RootModule {
    private Context context;

    public RootModule(BaseApplication application) {
        this.context = application.getApplicationContext();
    }

    @Provides
    @Singleton
    Context provideContext() {
        return context;
    }
}

Injecting your Presenter-class to your activity is not so easy, because in your constructor you have this MyView-parameter, which could not be set by Dagger. You could rethink your design by providing a setMyView-method in your MyPresenter-class instead of using a constructor-parameter.

Edit: Creating RootModule

public class BaseApplication extends Application {
    // Store Objectgraph as member attribute or use a Wrapper-class or...

    @Override
    public void onCreate() {
        super.onCreate();
        OBJECTGRAPH = ObjectGraph.create(getInjectionModule());
    } 

    protected Object getInjectionModule() {
        return new RootModule(this);
    }
}
like image 120
Christopher Avatar answered Oct 02 '22 21:10

Christopher