marc_aragones
marc_aragones

Reputation: 4474

Dagger inject not working for Retrofit

I am trying to use Dagger 2 for instantiating a Retrofit interface. The CloudContactDataStore class injects the RestClient and calls its methods.

When I instantiate a CloudContactDataStore object, its RestClient attribute has null value.

public class CloudContactDataStore implements ContactDataStore {

    @Inject RestClient restClient;

    public CloudContactDataStore() {
        this.initializeInjector();
    }

    private void initializeInjector() {
        DaggerApiComponent.builder()
                .apiModule(new ApiModule())
                .build()
                .inject(this);
    }

    @Override
    public Observable<ContactEntity> contactLogin(String contactId) {
        return this.restClient.contactLogin(contactId); // Here restClient is null!
    }
}

Here is how I create the Dagger Module and Component:

@Singleton
@Component(modules = ApiModule.class)
public interface ApiComponent {
    void inject(ContactDataStore contactDataStore);
}

@Module
public class ApiModule {

    @Provides public RestClient provideRestClient(ApiService apiService) {
        return new RestClientImpl(apiService);
    }

    @Provides public ApiService provideApiService(RestAdapter restAdapter) {
        return restAdapter.create(ApiService.class);
    }

    @Provides public RestAdapter provideRestAdapter() {
        return RestApiAdapter.getInstance();
    }
}

Now, the RestClient class and its implementation:

public interface RestClient {
    Observable<ContactEntity> contactLogin(String contactId);
}

public class RestClientImpl implements RestClient {

    ApiService apiService;

    @Inject
    public RestClientImpl(ApiService apiService) {
        this.apiService = apiService;
    }

    @Override
    public Observable<ContactEntity> contactLogin(String contactId) {
        return apiService.login(contactId, "xxx-xxx-xxx");
    }
}

The ApiService interface is the Retrofit interface:

public interface ApiService {

    String API_BASE_URL = "http://192.168.1.2";

    @POST("/login")
    Observable<ContactEntity> login(@Body String id, @Header("Key") String key);

}

And finally, the RestApiAdapter:

public class RestApiAdapter {

    private static RestAdapter sharedInstance = null;

    public static RestAdapter getInstance() {
        if (sharedInstance == null){


            sharedInstance = new RestAdapter.Builder()
                    .setLogLevel(RestAdapter.LogLevel.FULL)
                    .setEndpoint(ApiService.API_BASE_URL)
                    .build();
        }

        return sharedInstance;
    }
}

Can anyone see what I am doing wrong?

Thanks!

Upvotes: 0

Views: 1111

Answers (1)

Paul Duffin
Paul Duffin

Reputation: 201

This has the same problem as in Why Dagger inject is not working but component.getObject yes and the same solution. That is you need to either change your inject(ContactDataStore) method to inject(CloudContactDataStore) so it can see the field that needs injecting, or you need to add a method in ContactDataStore that allows you to inject the method yourself.

Upvotes: 1

Related Questions