2015-10-05 25 views
0

我想用Dagger 2來實例化一個Retrofit接口。 CloudContactDataStore類將注入RestClient並調用其方法。爲什麼Dagger注入不起作用,但component.getObject是

當我實例化一個CloudContactDataStore對象時,其RestClient屬性具有null值。

public class CloudContactDataStore implements ContactDataStore { 

    @Inject RestClient restClient; 

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

    private void initializeInjector() { 
     ApiComponent component = DaggerApiComponent.builder() 
      .apiModule(new ApiModule()) 
      .build(); 

     component.inject(this); // Nothing changes, restClient is null! 

     this.restClient = component.getRestClient(); // This works 
    } 
} 

這裏是我創建的匕首模塊和組件:

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

    RestClient getRestClient(); 
} 

@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(); 
    } 
} 

那麼,爲什麼inject功能不工作,但調用componentgetRestClient()是嗎?

回答

1

我發現查看Dagger 2生成的代碼非常有用,因爲它很容易遵循,並且可以經常指向正確的方向。

Dagger 2創建的代碼很像你寫的,所以想想你將如何實現ApiComponent.inject(ContactDataStore)。假設在該方法中,您可以訪問RestClient,那麼您如何才能進入該領域?如果你坐下來,寫了它,你會發現,你必須做這樣的事情:

((CloudContactDataStore) contactDataStore).restClient = restClient; 

或者在你需要它轉換到一個具體的實施等字樣。匕首2沒有被擊倒,EVER(至少我沒有看到它),因爲這通常是不安全的。

所以,你有兩個選擇。該方法inject(ContactDataStore)改變inject(CloudContactDataStore),或提供關於ContactDataStore的方法,其允許在RestClient要傳遞

更新:它不可能通過抽象的,即,接口,方法@注入。

如果你想通過ContactDataStore API注入它,那麼你有一個問題,因爲目前在匕首2的限制(都提出了功能要求將其刪除),你不能用@Inject標誌着一個抽象方法。因此,在此期間(或者永遠,如果有理由不能在Dagger 2中工作),則需要手動完成,即從組件方法獲取RestClient的實例,並將其傳遞給接口上的相應方法。

相關問題