Dagger 2 多个存储库
Dagger 2 multiple Repositories
所以我是 Dagger 2 依赖注入的新手。我创建了一个自定义 ViewModelFactory class,其中 returns 我的 ViewModel。
@Singleton
public class CustomViewModelFactory implements ViewModelProvider.Factory {
private final MyCatchesRepository repository;
@Inject
public CustomViewModelFactory(MyCatchesRepository repository) {
this.repository = repository;
}
@NonNull
@Override
@SuppressWarnings("unchecked")
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (modelClass.isAssignableFrom(MyCatchViewModel.class)) {
return (T) new MyCatchViewModel(repository);
} else {
throw new IllegalArgumentException("ViewModel Not Found");
}
}
}
CustomViewModel
在构造函数中获取 MyCatchesRepository
,然后创建 MyCatchViewModel
。
我如何更改此 class 以便我可以使用此 ViewModelFactory 创建具有不同构造函数参数(存储库)的不同 ViewModels
这是创建 CustomViewModelFactory 的模块
@Module
public class RoomModule {
private final MyDatabase myDatabase;
public RoomModule(Application application) {
this.myDatabase = Room.databaseBuilder(application,
MyDatabase.class, AppConstants.DATABASE_NAME)
.build();
}
@Provides
@Singleton
MyCatchesRepository provideCatchesRepository(MyCatchDao myCatchDao) {
return new MyCatchesRepository(myCatchDao);
}
@Provides
@Singleton
MyCatchDao providesCatchDao(MyDatabase myDatabase) {
return myDatabase.myCatchDao();
}
@Provides
@Singleton
LuresRepository provideLureRepository(LureDao lureDao) {
return new LuresRepository(lureDao);
}
@Provides
@Singleton
LureDao provideLureDao(MyDatabase myDatabase) {
return myDatabase.lureDao();
}
@Provides
@Singleton
MyDatabase provideDatabase(Application application) {
return myDatabase;
}
@Provides
@Singleton
ViewModelProvider.Factory provideCatchesViewModelFactory(MyCatchesRepository catchesRepository) {
return new CustomViewModelFactory(catchesRepository);
}
}
ViewModelModule
@Module
public abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(MyCatchViewModel.class)
abstract ViewModel myCatchViewModel(MyCatchViewModel myCatchViewModel);
@Binds
@IntoMap
@ViewModelKey(FishingSpotViewModel.class)
abstract ViewModel fishingSpotViewModel(FishingSpotViewModel fishingSpotViewModel);
@Binds
abstract ViewModelProvider.Factory bindCustomViewModelFactory(CustomViewModelFactory customViewModelFactory);
}
Google 团队在架构组件示例中提出的方法是使用自定义注释,以便通过 Dagger 提供 ViewModel 类。
在 Java 中,注释如下所示。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import androidx.lifecycle.ViewModel;
import dagger.MapKey;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@MapKey
@interface ViewModelKey {
Class<? extends ViewModel> value();
}
这使用来自 Dagger 的 MapKey,其中任何带注释的 ViewModel 都将组成一个 Map,然后可以在您的 ViewModelFactory 中使用。
在 Google 示例中,ViewModelFactory 如下所示,其中使用构造函数注入,您可以访问 ViewModel 提供程序的映射。
public class ViewModelFactory implements ViewModelProvider.Factory {
private final Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModels;
@Inject
public ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModels) {
this.viewModels = viewModels;
}
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
Provider<ViewModel> viewModelProvider = viewModels.get(modelClass);
if (viewModelProvider == null) {
throw new IllegalArgumentException("model class " + modelClass + " not found");
}
//noinspection unchecked
return (T) viewModelProvider.get();
}
}
在您的示例中,您最终会得到以下内容以提供 MyCatchViewModel。然后可以按照相同的模式提供其他 ViewModel。
@Module
public abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(MyCatchViewModel.class)
abstract ViewModel myCatchViewModel(MyCatchViewModel myCatchViewModel);
}
如需完整示例,您可以查看 Google 中的 GithubBrowserSample 示例。 https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample/app/src/main/java/com/android/example/github/di/ViewModelModule.kt
所以我是 Dagger 2 依赖注入的新手。我创建了一个自定义 ViewModelFactory class,其中 returns 我的 ViewModel。
@Singleton
public class CustomViewModelFactory implements ViewModelProvider.Factory {
private final MyCatchesRepository repository;
@Inject
public CustomViewModelFactory(MyCatchesRepository repository) {
this.repository = repository;
}
@NonNull
@Override
@SuppressWarnings("unchecked")
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (modelClass.isAssignableFrom(MyCatchViewModel.class)) {
return (T) new MyCatchViewModel(repository);
} else {
throw new IllegalArgumentException("ViewModel Not Found");
}
}
}
CustomViewModel
在构造函数中获取 MyCatchesRepository
,然后创建 MyCatchViewModel
。
我如何更改此 class 以便我可以使用此 ViewModelFactory 创建具有不同构造函数参数(存储库)的不同 ViewModels
这是创建 CustomViewModelFactory 的模块
@Module
public class RoomModule {
private final MyDatabase myDatabase;
public RoomModule(Application application) {
this.myDatabase = Room.databaseBuilder(application,
MyDatabase.class, AppConstants.DATABASE_NAME)
.build();
}
@Provides
@Singleton
MyCatchesRepository provideCatchesRepository(MyCatchDao myCatchDao) {
return new MyCatchesRepository(myCatchDao);
}
@Provides
@Singleton
MyCatchDao providesCatchDao(MyDatabase myDatabase) {
return myDatabase.myCatchDao();
}
@Provides
@Singleton
LuresRepository provideLureRepository(LureDao lureDao) {
return new LuresRepository(lureDao);
}
@Provides
@Singleton
LureDao provideLureDao(MyDatabase myDatabase) {
return myDatabase.lureDao();
}
@Provides
@Singleton
MyDatabase provideDatabase(Application application) {
return myDatabase;
}
@Provides
@Singleton
ViewModelProvider.Factory provideCatchesViewModelFactory(MyCatchesRepository catchesRepository) {
return new CustomViewModelFactory(catchesRepository);
}
}
ViewModelModule
@Module
public abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(MyCatchViewModel.class)
abstract ViewModel myCatchViewModel(MyCatchViewModel myCatchViewModel);
@Binds
@IntoMap
@ViewModelKey(FishingSpotViewModel.class)
abstract ViewModel fishingSpotViewModel(FishingSpotViewModel fishingSpotViewModel);
@Binds
abstract ViewModelProvider.Factory bindCustomViewModelFactory(CustomViewModelFactory customViewModelFactory);
}
Google 团队在架构组件示例中提出的方法是使用自定义注释,以便通过 Dagger 提供 ViewModel 类。
在 Java 中,注释如下所示。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import androidx.lifecycle.ViewModel;
import dagger.MapKey;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@MapKey
@interface ViewModelKey {
Class<? extends ViewModel> value();
}
这使用来自 Dagger 的 MapKey,其中任何带注释的 ViewModel 都将组成一个 Map,然后可以在您的 ViewModelFactory 中使用。
在 Google 示例中,ViewModelFactory 如下所示,其中使用构造函数注入,您可以访问 ViewModel 提供程序的映射。
public class ViewModelFactory implements ViewModelProvider.Factory {
private final Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModels;
@Inject
public ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> viewModels) {
this.viewModels = viewModels;
}
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
Provider<ViewModel> viewModelProvider = viewModels.get(modelClass);
if (viewModelProvider == null) {
throw new IllegalArgumentException("model class " + modelClass + " not found");
}
//noinspection unchecked
return (T) viewModelProvider.get();
}
}
在您的示例中,您最终会得到以下内容以提供 MyCatchViewModel。然后可以按照相同的模式提供其他 ViewModel。
@Module
public abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(MyCatchViewModel.class)
abstract ViewModel myCatchViewModel(MyCatchViewModel myCatchViewModel);
}
如需完整示例,您可以查看 Google 中的 GithubBrowserSample 示例。 https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample/app/src/main/java/com/android/example/github/di/ViewModelModule.kt