使用Dagger 2,我有一个域名对象,我提供给演示者。该域对象依赖于存储库。该存储库有两个实现,但都实现了相同的接口。我需要能够以某种方式设置匕首,以便在运行时根据用户选择"演示模式"在存储库的两个实现之间进行交换。选项。
所以我有以下域对象:
public class SomeAwesomeBusinessLogic {
Repository repository;
@Inject
public SomeAwesomeBusinessLogic(Repository repository) {
this.repository = repository;
}
//awesome stuff goin down
}
这两个存储库:
public RemoteRepository implements Repository {
@Inject
public RemoteRepository() {
//setup
}
}
public DemoRepository implements Repository {
@Inject
public DemoRepository() {
//setup
}
}
关于如何构建我的模块和组件以使其工作的任何想法?
答案 0 :(得分:0)
我想到了几个想法。取决于您想要如何以及何时交换此信息。一种可能性是使用配置实例化您的模块。可以是一个简单的布尔值:
@Module
public class RepositoryModule {
private final boolean isDemo;
public RepositoryModule(boolean isDemo) {
this.isDemo = isDemo;
}
@Provides
public Repository providesRepository() {
return isDemo? new DemoRepository() : new RemoteRepository();
}
// Other providers
}
我不是这种方法的粉丝,但它适合您的用例。我认为它具有相当的限制性,并且不易于维护。我或许会选择使用工厂并提供工厂而不是回购本身。
public interface RepositoryFactory {
Repository getRepository(Configuration configuration);
}
public class RepositoryFactoryImpl implements RepositoryFactory {
@Inject
public RepositoryFactoryImpl() {}
// The implementation
}
@Module
public class RepositoryModule {
@Provides
public RepositoryFactory providesRepositoryFactory(
RepositoryFactoryImpl factory) {
return factory;
}
// Other providers
}
Configuration
将是一个简单的POJO,您可以在其中指定几个属性来配置您的仓库。比如说:
public class Configuration {
private final boolean isDemo;
// all the POJO stuff you need
}
然后,您可以使您的域对象依赖于工厂:
public class SomeAwesomeBusinessLogic {
private final RepositoryFactory repositoryFactory;
@Inject
public SomeAwesomeBusinessLogic(
RepositoryFactory repositoryFactory) {
this.repositoryFactory = repositoryFactory;
}
//awesome stuff going down
}
然后,您可以在业务逻辑中执行repositoryFactory.getRepository(new Configuration(true/false));
。
我更喜欢这种方法,因为它更容易扩展到新类型的回购。您还可以测试工厂逻辑是否正确。没有人经常测试匕首模块,这就是为什么我不太热衷于第一种方法。
另一个好处是,这种方法允许您保留相同的模块实例,如果有可能通过提供不同的{{1}更改应用程序的配置并突然更改为演示回购对象到工厂。
第三种可能性可能是Producers。但是,这实际上取决于您的用例以及您希望如何处理此运行时依赖项交换。我发现这种方法非常好,但可能有点矫枉过正。
希望这有帮助