2014-12-10 18 views
7

Android projemde tek API bitiş noktası için aşağıdaki RetrofitApiModule kullanıyorum. Lütfen dikkat, enjekte bağımlılıkları için Dagger kullanıyorum.Retrofit kullanarak çoklu API bitiş noktalarını nasıl adreslenir?

@Module(
     complete = false, 
     library = true 
) 
public final class ApiModule { 

    public static final String PRODUCTS_BASE_URL = "https://products.com"; 

    @Provides 
    @Singleton 
    Endpoint provideEndpoint() { 
     return Endpoints.newFixedEndpoint(PRODUCTS_BASE_URL); 
    } 

    @Provides 
    @Singleton 
    ObjectMapper provideObjectMapper() { 
     ObjectMapper objectMapper = new ObjectMapper(); 
     objectMapper.setPropertyNamingStrategy(
      PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES); 
     return objectMapper; 
    } 

    @Provides 
    @Singleton 
    RestAdapter provideRestAdapter(
     Endpoint endpoint, ObjectMapper objectMapper) { 
     return new RestAdapter.Builder() 
       .setLogLevel(RestAdapter.LogLevel.NONE) 
       .setEndpoint(endpoint) 
       .setConverter(new JacksonConverter(objectMapper)) 
       .build(); 
    } 

    @Provides 
    @Singleton 
    ProductsService provideProductsService(RestAdapter restAdapter) { 
     return restAdapter.create(ProductsService.class); 
    } 

} 

Şimdi, iletişim kurmak istediğiniz başka API (örn "http://subsidiaries.com") yoktur. ve RestAdapter yeniden kullanılırken verilen ApiModule uzatılabilir mi? Yoksa uzatmamalı mıyım? Modülü çoğaltmaya çalıştım. Ancak bu, Endpoint, ObjectMapper'u kopyaladığım ve RestAdapter'un bir özel denetçisine sahip olduğumu içerir - bu yüzden yapamam.

+1

"ApiModule" kurucusunu hazırlayıp, son noktayı oraya iletemez ve tüm yöntemlerde IF koşuluna göre kod uygulayamazsınız? –

+0

@SweetWisher ツ Bağımlılık enjeksiyonu ** varsayılan yapıcıyı ** kullanır. Bu nedenle, farklı durumları elle işlemek için parametreleri aktarmak burada yardımcı olmaz. – JJD

cevap

4

Sana Named ek açıklamalarla işe yarayabilir sanırım:

@Module(
     complete = false, 
     library = true 
) 
public final class ApiModule { 

    public static final String PRODUCTS_BASE_URL = "https://products.com"; 
    public static final String SUBSIDIARIES_BASE_URL = "https://subsidiaries.com"; 

    public static final String PRODUCTS = "products"; 
    public static final String SUBSIDIARIES = "subsidiaries"; 

    @Provides 
    @Singleton 
    @Named(PRODUCTS) 
    Endpoint provideProductsEndpoint() { 
     return Endpoints.newFixedEndpoint(PRODUCTS_BASE_URL); 
    } 

    @Provides 
    @Singleton 
    @Named(SUBSIDIARIES) 
    Endpoint provideSubsidiariesEndpoint() { 
     return Endpoints.newFixedEndpoint(SUBSIDIARIES_BASE_URL); 
    } 

    @Provides 
    @Singleton 
    ObjectMapper provideObjectMapper() { 
     ObjectMapper objectMapper = new ObjectMapper(); 
     objectMapper.setPropertyNamingStrategy(
      PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES); 
     return objectMapper; 
    } 

    @Provides 
    @Singleton 
    @Named(PRODUCTS) 
    RestAdapter provideProductsRestAdapter(@Named(PRODUCTS) Endpoint endpoint, ObjectMapper objectMapper) { 
     return newRestAdapterBuilder(objectMapper) 
       .setEndpoint(endpoint) 
       .build(); 
    } 

    @Provides 
    @Singleton 
    @Named(SUBSIDIARIES) 
    RestAdapter provideSubsidiariesRestAdapter(@Named(SUBSIDIARIES) Endpoint endpoint, ObjectMapper objectMapper) { 
     return newRestAdapterBuilder(objectMapper) 
       .setEndpoint(endpoint) 
       .build(); 
    } 

    @Provides 
    @Singleton 
    @Named(PRODUCTS) 
    ProductsService provideProductsService(@Named(PRODUCTS) RestAdapter restAdapter) { 
     return restAdapter.create(ProductsService.class); 
    } 

    @Provides 
    @Singleton 
    @Named(SUBSIDIARIES) 
    ProductsService provideSubsidiariesService(@Named(SUBSIDIARIES) RestAdapter restAdapter) { 
     return restAdapter.create(ProductsService.class); 
    } 

    private RestAdapter.Builder newRestAdapterBuilder(ObjectMapper objectMapper) { 
     return new RestAdapter.Builder() 
         .setLogLevel(RestAdapter.LogLevel.NONE) 
         .setConverter(new JacksonConverter(objectMapper)); 
    } 
} 

Şimdi her yerde ProductsService İhtiyacınız varyantın hangi bağlı @Named(PRODUCTS) veya @Named(SUBSIDIARIES) ile bağımlılığı açıklama yapmalı ya enjekte nerede. Tabii ki @Named ek açıklamaları yerine kendi özel notlarınızı da oluşturabilir ve kullanabilirsiniz. "Qualifiers" altında here'a bakın.

Modülünüzü biraz düzleştirmek için RestAdapters öğesinin oluşturulmasını provide*Service() yöntemlerine taşıyabilir ve provide*RestAdapter() yöntemlerinden kurtulursunuz. RestAdapters'a, modülün dışında bir bağımlılık olarak ihtiyaç duymadıkça, elbette.

İlgili konular