I'm wondering if there is a way for Dagger to know that it should recreate an object when new data is available.
The instance I am speaking of is with the request headers I have for retrofit. At some point (when the user logs in) I get a token that I need to add to the headers of retrofit to make authenticated requests. The issue is, I'm left with the same unauthenticated version of retrofit. Here's my injection code:
@Provides
@Singleton
OkHttpClient provideOkHttpClient(Cache cache) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.cache(cache).build();
client
.newBuilder()
.addInterceptor(
chain -> {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder()
.addHeader("Accept", "Application/JSON");
Request request = requestBuilder.build();
return chain.proceed(request);
}).build();
return client;
}
@Provides
@Singleton
Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) {
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxErrorHandlingCallAdapterFactory.create())
.baseUrl(mBaseUrl)
.client(okHttpClient)
.build();
return retrofit;
}
@Provides
@Singleton
public NetworkService providesNetworkService(Retrofit retrofit) {
return retrofit.create(NetworkService.class);
}
Any ideas on how to make this work?
I personally created an okhttp3.Interceptor
that does that for me, which I update once I have the required token. It looks something like:
@Singleton
public class MyServiceInterceptor implements Interceptor {
private String sessionToken;
@Inject public MyServiceInterceptor() {
}
public void setSessionToken(String sessionToken) {
this.sessionToken = sessionToken;
}
@Override public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder requestBuilder = request.newBuilder();
if (request.header(NO_AUTH_HEADER_KEY) == null) {
// needs credentials
if (sessionToken == null) {
throw new RuntimeException("Session token should be defined for auth apis");
} else {
requestBuilder.addHeader("Cookie", sessionToken);
}
}
return chain.proceed(requestBuilder.build());
}
}
In the corresponding dagger component, I expose this interceptor so I can set the sessionToken
when I need to.
That is some stuff that Jake talked about it his talk Making Retrofit Work For You.