我我的應用程序轉換爲MVP架構,發現匕首2在需要時是有用的注入依賴的多個實例。我的應用需要與兩個網絡apis(我自己和第三方api)進行通信。有些時候,我自己的api和第三方api的請求可能會同時觸發。我正在使用Retrofit與這些apis進行通信,並使用GSON進行序列化/反序列化。
我做什麼之前
我創建了兩個改造RestAdapters和使用Service Locator模式在需要時獲得他們。旨在用於我自己的api的RestAdapter包括帶有一些自定義TypeAdapter的GSONConverter,因爲我不想在應用程序中對我的響應進行1:1 JSON反序列化。另一個RestAdapter用於第三方API,並使用另一個具有特定字段命名策略的GSONConverter。
問題
我想使用DI,而不是服務定位器來獲得我的RestAdapter(和API接口)。我有我的NetModule類設置像如下
@Module
public class NetModule {
private static final String MY_API_URL = "my_api_url";
private static final String THIRD_PARTY_API_URL = "third_party_api_url";
@Provides
@Singleton
Cache provideOkHttpCache(Application application) {
int cacheSize = 10 * 1024 * 1024; // 10 MiB
return new Cache(application.getCacheDir(), cacheSize);
}
@Provides
@Singleton
OkHttpClient provideOkHttpClient(Cache cache) {
OkHttpClient client = new OkHttpClient();
client.setCache(cache);
return client;
}
@Provides
@Singleton
TypeAdapter<MyClass> provideMyAPITypeAdapter() {
return new TypeAdapter<MyClass>() {
// implementation ignored
};
}
@Provides
@Named("myApiGson")
Gson provideGsonForMyAPI(TypeAdapter<MyClass> adapter) {
return new GsonBuilder()
.registerTypeAdapter(MyClass.class, adapter)
.setDateFormat("yyyy-MM-dd HH:mm:ss")
.create();
}
@Provides
@Named("thirdPartyApiGson")
Gson provideGsonForThirdPartyAPI() {
return new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create();
}
@Provides
@Named("myApiRestAdapter")
RestAdapter provideMyRestAdapter(Gson gson, OkHttpClient okHttpClient) {
return new RestAdapter.Builder()
.setEndpoint(MY_API_URL)
.setConverter(new GsonConverter(gson))
.setClient(new OkClient(okHttpClient))
.build();
}
@Provides
@Named("thirdPartyApiRestAdapter")
RestAdapter provideThirdPartyRestAdapter(Gson gson, OkHttpClient okHttpClient) {
return new RestAdapter.Builder()
.setEndpoint(THIRD_PARTY_API_URL)
.setConverter(new GsonConverter(gson))
.setClient(new OkClient(okHttpClient))
.build();
}
@Provides
@Singleton
MyAPI provideMyAPI(RestAdapter adapter){
return adapter.create(MyAPI.class);
}
@Provides
@Singleton
ThirdPartyAPI provideThirdPartyAPI(RestAdapter adapter){
return adapter.create(ThirdPartyAPI.class);
}
}
正如你可以在代碼中看到上述情況,NetModule有方法返回兩個GSON對象和兩個RestAdapter對象。我的問題是;
我如何確保創建特定RestAdapter & API接口時,正確的依賴注入? (
provideMyRestAdapter()
需要GSON從provideGsonForMyAPI()
回來,provideMyAPI()
需要RestAdapter從provideMyRestAdapter()
返回。)我怎樣才能確保(一個用於我的API和其他第三方API)RestAdapter的只有兩個實例的生命週期過程中所創造因爲創建RestAdapter的應用程序被認爲是昂貴的。我在返回RestAdapters的方法上使用
@Named
屬性。比如說,當像這樣直接向字段注入依賴關係時:@Inject("myApiRestAdapter") RestAdapter myRestadapter;
是Dagger 2每次都要創建新的RestAdapter,還是要使用之前創建的(比如@Singleton
,但是用於特定對象)?
我剛開始用匕首2和我的如何使用它理解可能仍然是不正確的。如果我在這裏做錯了,請糾正我。感謝您支持這個長期的問題。
謝謝@pratt我會試試看。我有一個問題,是不是'@ Singleton'應該只爲給定的類類型創建一個對象?在這種情況下,如果我將其餘的適配器註釋爲@ @ Singleton(RestAdapter類型),幕後會發生什麼? –
除了將您的方法註釋爲'@ Singleton',您還可以使用'@ Named'註釋對其進行註釋,該註釋將告訴匕首爲每個名稱創建RestAdapter的兩個不同實例。請確保通過使用'@ Named'來引用您需要的RestAdapter,就像我在上面的答案中所顯示的那樣。 – Harry
這很有道理,謝謝。我今晚會嘗試這個,回到你身邊! –