Dagger的运行时交换实现提供了依赖性

时间:2017-03-16 20:30:43

标签: dagger-2

使用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
    }
}

关于如何构建我的模块和组件以使其工作的任何想法?

1 个答案:

答案 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。但是,这实际上取决于您的用例以及您希望如何处理此运行时依赖项交换。我发现这种方法非常好,但可能有点矫枉过正。

希望这有帮助

相关问题