Dependency Injection

You may have heard of Dependency Injection and the huge benefit it brings up to your application development. With Robo MVP, you can easily employ some of the best Dependency Injection frameworks in developing applications.

Google Guice

In Gradle

Add following dependencies to your build.gradle:

dependencies {
    compile 'com.google.inject:guice:3.0:no_aop'
    compile 'com.robocreative.android:robo-mvp-guice:1.0'
}
Sample

Let's say you have a SearchEngine being responsible for searching and returning SearchResult for every search operation. The SearchPresenter delegates searching to SearchEngine and asks the SearchView to display SearchResult.

package com.example.myapplication;

/**
 * Defines a search engine.
 */
public interface SearchEngine {

    /**
     * Searches for a specified pattern.
     */
    SearchResult search(String pattern);
}

Inject the SearchEngine to SearchPresenter by using @Inject on top of presenter's constructor.

package com.example.myapplication;

import com.google.inject.Inject;
import com.robo.mvp.AbstractPresenter;

/**
 * The presenter acts upon the SearchView.
 */
public class SearchPresenter extends AbstractPresenter<SearchView> {

    private SearchEngine mSearchEngine;

    @Inject
    public SearchPresenter(SearchEngine searchEngine) {
        mSearchEngine = searchEngine;
    }

    @Override
    protected void onViewSet(final SearchView view) {
        view.getListeners().set(SearchView.OnSearchListener.class, new SearchView.OnSearchListener() {
            @Override
            public void onSearch(String pattern) {
                // asks view to display search result returned from search operation.
                view.displayResult(mSearchEngine.search(pattern));
            }
        });
    }
}

In case of using multiple implementation of search engine (e.g Google, Bing etc.), you can use @Named to specify which implementation will be used.

@Inject
public SearchPresenter(@Named("Google") SearchEngine searchEngine) {
    mSearchEngine = searchEngine;
}

To register components to the container, use derivative of AbstractModule. You might have multiple modules at a time.

package com.example.myapplication;

import com.google.inject.AbstractModule;
import com.google.inject.name.Names;

public class SearchModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(SearchEngine.class).annotatedWith(Names.named("Google")).to(GoogleSearchEngine.class);
        bind(SearchEngine.class).annotatedWith(Names.named("Bing")).to(BingSearchEngine.class);
        // and more...
    }
}

To register modules, create your bootstrapper as a derivative of com.robo.mvp.guice.AbstractBoostrapper and attach your application modules to module list.

package com.example.myapplication;

import com.google.inject.AbstractModule;
import com.robo.mvp.guice.AbstractBootstrapper;

import java.util.ArrayList;
import java.util.Collection;

public class MyBootstrapper extends AbstractBootstrapper {
    @Override
    protected Collection<AbstractModule> collectModules() {
        Collection<AbstractModule> modules = new ArrayList<>();
        modules.add(new SearchModule());
        return modules;
    }
}

Finally, start your bootstrapper in your application class. Don't forget to specify application name in AndroidManifest.xml.

package com.example.myapplication;

import android.app.Application;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        new MyBootstrapper().start();
    }
}
Dependency Injection extension also supports Command Binding. You can find this feature in Presenter Features section.