Dagger2 - 将 Object 传递给模块的最佳实践?
Dagger2 - Best practice for passing an Object to a Module?
我正在尝试创建 RetrofitModule
。我有一个 interceptor
,它使用 AuthHeader
object 添加动态 headers。我不确定如何将此 object 传递给模块 class.
@Module
public class RetrofitModule {
private static final String TAG = "RetrofitModule";
//Do I create a constructor here for the RetrofitModule that accepts an AuthHeader object?
@Provides
@Singleton
RequestInterceptor providesRequestInterceptor(@NonNull AuthHeader authHeader) {
return new RequestInterceptor(authHeader);
}
@Provides
@Singleton
OkHttpClient.Builder provideOkHttp() {
return new OkHttpClient.Builder();
}
@Provides
@Singleton
Retrofit provideRetrofit(OkHttpClient.Builder okHttpClient, RequestInterceptor requestInterceptor) {
okHttpClient.addInterceptor(requestInterceptor);
HttpLoggingInterceptor logging = new HttpLoggingInterceptor().setLevel(
HttpLoggingInterceptor.Level.BASIC
);
okHttpClient.addInterceptor(logging);
return new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(Constants.ENDPOINT)
.client(okHttpClient.build())
.build();
}
@Provides
@Singleton
LoginService provideLoginServer(Retrofit retrofit) {
return retrofit.create(LoginService.class);
}
}
这是我要传递给模块的 AuthHeader
object 以便我可以将动态 headers 添加到网络调用中:
public class AuthHeader {
private String idToken;
private String idClient;
private String idEmail;
public AuthHeader(String idToken, String idClient, String idEmail) {
this.idToken = idToken;
this.idClient = idClient;
this.idEmail = idEmail;
}
public String getIdToken() {
return idToken;
}
public String getIdClient() {
return idClient;
}
public String getIdEmail() {
return idEmail;
}
}
根据您的意见,您想从 SharedPreferences 读取令牌,我提供了一个完整的示例:
除了您的代码,我还创建了 AuthInfoProvider
可以读取和提供身份验证信息。它用于代替传递 AuthHeader 对象。
class AuthInfoProvider {
SharedPreferences preferences;
public AuthInfoProvider(Context context) {
preferences = context.getSharedPreferences("MyPreferences", Context.MODE_PRIVATE);
}
public String getToken() {
return preferences.getString("MyToken", "");
}
}
将 AuthInfoProvider
传递给拦截器:
它为每个 API 调用检索令牌。
class RequestInterceptor implements Interceptor {
private final AuthInfoProvider provider;
public RequestInterceptor(AuthInfoProvider provider) {
this.provider = provider;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("Authentication", provider.getToken())
.build();
return chain.proceed(request);
}
}
现在我们应该将它传递给我们的模块
@Module
public class RetrofitModule {
private static final String TAG = "RetrofitModule";
@Provides
@Singleton
public static AuthInfoProvider providesAuthInfoProvider(Context context) {
return new AuthInfoProvider(context);
}
@Provides
@Singleton
public static RequestInterceptor providesRequestInterceptor(@NonNull AuthInfoProvider authInfoProvider) {
return new RequestInterceptor(authInfoProvider);
}
// other your methods
// just make them static
}
组件将是这样的:
@Singleton
@Component(modules = RetrofitModule.class)
interface NetworkComponent {
@Component.Builder
interface Builder {
Builder bindContext(@BindsInstance Context context);
NetworkComponent build();
}
void inject(SampleFragment fragment);
}
并将上下文传递给组件并像这样构建它:
DaggerNetworkComponent.builder()
.bindContext(getContext())
.build()
.inject(this);
我正在尝试创建 RetrofitModule
。我有一个 interceptor
,它使用 AuthHeader
object 添加动态 headers。我不确定如何将此 object 传递给模块 class.
@Module
public class RetrofitModule {
private static final String TAG = "RetrofitModule";
//Do I create a constructor here for the RetrofitModule that accepts an AuthHeader object?
@Provides
@Singleton
RequestInterceptor providesRequestInterceptor(@NonNull AuthHeader authHeader) {
return new RequestInterceptor(authHeader);
}
@Provides
@Singleton
OkHttpClient.Builder provideOkHttp() {
return new OkHttpClient.Builder();
}
@Provides
@Singleton
Retrofit provideRetrofit(OkHttpClient.Builder okHttpClient, RequestInterceptor requestInterceptor) {
okHttpClient.addInterceptor(requestInterceptor);
HttpLoggingInterceptor logging = new HttpLoggingInterceptor().setLevel(
HttpLoggingInterceptor.Level.BASIC
);
okHttpClient.addInterceptor(logging);
return new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(Constants.ENDPOINT)
.client(okHttpClient.build())
.build();
}
@Provides
@Singleton
LoginService provideLoginServer(Retrofit retrofit) {
return retrofit.create(LoginService.class);
}
}
这是我要传递给模块的 AuthHeader
object 以便我可以将动态 headers 添加到网络调用中:
public class AuthHeader {
private String idToken;
private String idClient;
private String idEmail;
public AuthHeader(String idToken, String idClient, String idEmail) {
this.idToken = idToken;
this.idClient = idClient;
this.idEmail = idEmail;
}
public String getIdToken() {
return idToken;
}
public String getIdClient() {
return idClient;
}
public String getIdEmail() {
return idEmail;
}
}
根据您的意见,您想从 SharedPreferences 读取令牌,我提供了一个完整的示例:
除了您的代码,我还创建了 AuthInfoProvider
可以读取和提供身份验证信息。它用于代替传递 AuthHeader 对象。
class AuthInfoProvider {
SharedPreferences preferences;
public AuthInfoProvider(Context context) {
preferences = context.getSharedPreferences("MyPreferences", Context.MODE_PRIVATE);
}
public String getToken() {
return preferences.getString("MyToken", "");
}
}
将 AuthInfoProvider
传递给拦截器:
它为每个 API 调用检索令牌。
class RequestInterceptor implements Interceptor {
private final AuthInfoProvider provider;
public RequestInterceptor(AuthInfoProvider provider) {
this.provider = provider;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("Authentication", provider.getToken())
.build();
return chain.proceed(request);
}
}
现在我们应该将它传递给我们的模块
@Module
public class RetrofitModule {
private static final String TAG = "RetrofitModule";
@Provides
@Singleton
public static AuthInfoProvider providesAuthInfoProvider(Context context) {
return new AuthInfoProvider(context);
}
@Provides
@Singleton
public static RequestInterceptor providesRequestInterceptor(@NonNull AuthInfoProvider authInfoProvider) {
return new RequestInterceptor(authInfoProvider);
}
// other your methods
// just make them static
}
组件将是这样的:
@Singleton
@Component(modules = RetrofitModule.class)
interface NetworkComponent {
@Component.Builder
interface Builder {
Builder bindContext(@BindsInstance Context context);
NetworkComponent build();
}
void inject(SampleFragment fragment);
}
并将上下文传递给组件并像这样构建它:
DaggerNetworkComponent.builder()
.bindContext(getContext())
.build()
.inject(this);