What is the reason for separating RestAdapter.build () and .create () methods when using a dagger?

I have been using Dagger / Retrofit for the past few months and have seen the general implementation of the ApiModule class for api. These ApiModules usually look something like this:

@Provides @Singleton Client provideClient(OkHttpClient client) {
    return new OkClient(client);
  }

  @Provides @Singleton Endpoint provideEndpoint() {
    return "release".equalsIgnoreCase(BuildConfig.BUILD_TYPE)
        ? Endpoints.newFixedEndpoint(PRODUCTION_URL, "Foo Production Url")
        : Endpoints.newFixedEndpoint(STAGING_URL, "Foo Staging Url");
  }

  @Provides @Singleton Converter provideConverter(Gson gson) {
    return new GsonConverter(gson);
  }

  @Provides @Singleton RestAdapter provideRestAdapter(Endpoint endpoint, Client client,
      Converter converter) {
    return new RestAdapter.Builder()
        .setClient(client)
        .setEndpoint(endpoint)
        .setConverter(converter)
        .setLogLevel(BuildConfig.DEBUG
            ? RestAdapter.LogLevel.FULL
            : RestAdapter.LogLevel.NONE)
        .build();
  }

  @Provides @Singleton FooApi provideFooApi(RestAdapter restAdapter) {
    return restAdapter.create(FooApi.class);
  }

      

But to clean it up, why not do this:

@Provides @Singleton Client provideClient(OkHttpClient client) {
        return new OkClient(client);
      }

@Provides @Singleton Converter provideConverter(Gson gson) {
        return new GsonConverter(gson);
      }

@Provides @Singleton FooApi provideFooApi(Client client, Converter converter) {
    return new RestAdapter.Builder()
        .setClient(client)
        .setEndpoint("release".equalsIgnoreCase(BuildConfig.BUILD_TYPE)
            ? Endpoints.newFixedEndpoint(PRODUCTION_URL, "Foo Production Url")
            : Endpoints.newFixedEndpoint(STAGING_URL, "Foo Staging Url"))
        .setConverter(converter)
        .setLogLevel(BuildConfig.DEBUG
            ? RestAdapter.LogLevel.FULL
            : RestAdapter.LogLevel.NONE)
        .build()
        .create(FooApi.class);
  }

      

Are there any downsides to this, or am I breaking my contract with the dagger? I am asking because there have been cases where I need to use multiple APIs in a project ... setting it up like the second example above makes this possible.

+3


source to share


1 answer


There are three reasons for this:



  • By separating the two, you create a separation of concerns. How the instance RestAdapter

    is instantiated and placed on the graph is completely different from how the instance of our service interface is placed on the graph. Here you have them in one module, but there is no reason why they cannot be in separate modules, or even have one in a library from another component.

  • Individual providers allow you to override one or both in an override module to customize the behavior without knowing how the other is being used or where it happens.

    For example, if you want to enable different behavior when you run an integration test, you can provide a different instance RestAdapter

    .

    @Provides @Singleton RestAdapter provideTestRestAdapter() {
      return new RestAdapter.Builder()
          .setEndpoint(Endpoints.newFixedEndpoint("http://mycomputer.local/api"))
          .setLogLevel(FULL)
          .build();
    }
    
          

    Having this in the override module means you don't need to change where the service instances are created.

  • Finally, and simply put, you might have multiple service interfaces. You shouldn't create multiple instances RestAdapter

    (unless they are intended for different endpoints).

    @Provides @Singleton AccountService provideAccountService(RestAdapter ra) {
      return ra.create(AccountService.class);
    }
    
    @Provides @Singleton TweetService provideTweetService(RestAdapter ra) {
      return ra.create(TweetService.class);
    }
    
    @Provides @Singleton DirectMessageService provideDirectMessageService(RestAdapter ra) {
      return ra.create(DirectMessageService.class);
    }
    
          

+6


source







All Articles