How to inject context into a non-active class?
I am trying to inject Context into a non-activity class. In my case, I am trying to inject a model class (from MVP pattern). I need a Context to get a string from resources. The result of the () method returns an Observable, which returns a ViewModel, which is the modified API model. The ViewModel is used for display in MainActivity. I tried this code, but Context is null, I think it is not injected.
public class MainActivityModel implements MainActivityMVP.Model {
@Inject
Context context;
private Repository repository;
public MainActivityModel(Repository repository) {
((App) getApplication()).getComponent().inject(this); //Cannot resolve getApplication() method :(
this.repository = repository;
}
@Override
public Observable<List<ViewModel>> result(String username) {
return repository.getRepositories(username).map(new Func1<List<Repository>, List<ViewModel>>() {
@Override
public List<ViewModel> call(List<Repository> repositories) {
List<ViewModel> viewModelList = new ArrayList<ViewModel>();
for (Repository repository : repositories) {
// here Context is null
viewModelList.add(new ViewModel(context.getString(R.string.repository) + repository.getName()));
}
return viewModelList;
}
});
}
}
This is the Component class, which has an injection method (MainActivityModel target) that I cannot use to inject the MainActivityModel since getApplication is not available from the non-Activity class:
@Singleton
@Component(modules = {ApplicationModule.class, MainActivityModule.class, GithubApiModule.class})
public interface ApplicationComponent {
void inject(MainActivity target);
void inject(MainActivityModel target);
}
I think the Context can be sent via the result method (String username, Context context). But what is the point of Dependency Injection if I pass the Context as a method parameter? I may have misunderstood the fundamental concept of DI.
So my question is, is it possible to inject context into a class without activity? Or should it be passed as a method parameter?
source to share
To inject context, you need to write a module using a provide method:
@Module (injects = {MainActivityModel.class})
public class RootModule {
private Context context;
public RootModule(App application) {
this.context = application.getApplicationContext();
}
@Provides
@Singleton
Context provideContext() {
return context;
}
}
In your custom App class:
public class App extends Application {
public ObjectGraph objectGraph;
@Override
public void onCreate() {
super.onCreate();
objectGraph = ObjectGraph.create(getInjectionModule());
}
protected Object getInjectionModule() {
return new RootModule(this);
}
}
And add to the model constructor:
public MainActivityModel(Repository repository) {
((App) getApplication()).objectGraph.inject(this);
this.repository = repository;
}
source to share