Search code examples
androiddependency-injectiondagger-2dagger

How to inject a Retrofit object directly into a repository class?


I want to inject a Retrofit object directly into my MyRepository class but I always get a NullPointerException. This is what I have tried.

This is my AppModule class:

@Module
public class AppModule {
    @Singleton
    @Provides
    static Retrofit provideRetrofitInstance(){
        return new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
}

And this is my view model class:

public class MyViewModel extends AndroidViewModel {
    LiveData<Data> myLiveData;

    MyViewModel(Application application, City city) {
        super(application);
        myLiveData = myRepository.addDataToLiveData(city);
    }

    LiveData<Data> getLiveData() {
        return myLiveData;
    }
}

And this is my repository class where I want to inject Retofit:

public class MyRepository {
    private String myTex;
    @Inject
    private Retrofit retrofit;

    public MyRepository(String myText) {
        this.myText = myText;
    }

    LiveData<Data> addDataToLiveData(City city) {
        //Make api call using retrofit
    }
}

Edit:

This is how I instantiate my ViewModel in my activity class:

MyRepository repository = new MyRepository("MyText");
Application application = activity.getApplication();
MyViewModelFactory factory = new MyViewModelFactory(application, repository);
MyViewModel viewModel = ViewModelProviders.of(this, factory).get(MyViewModel.class);

Solution

  • Making your Repository injectable is the simplest solution, which also allows you to inject it where it's used, in your ViewModels or Interactors:

    @Singleton
    public class MyRepository {
    
        private Retrofit retrofit;
    
        @Inject
        public MyRepository(Retrofit retrofit) {
            this.retrofit = retrofit;
        }
    
        LiveData<Data> addDataToLiveData(City city) {
            //Make api call using retrofit
        }
    }
    

    Edit: you can either provide the text via Dagger and inject that in your constructor, like this

    @Inject
    public MyRepository(String myText, Retrofit retrofit)
    

    Note that you'd need to use @Named or @Qualifier for your string.

    Alternatively, you can inject your repository calling inject(this), the syntax depends on how you setup Dagger

    somehowGetDaggerComponent().inject(this)
    

    I strongly suggest you go with the 1st solution.