Dagger如何在代码中注入一个实现

问题描述 投票:0回答:1

我是Android开发人员,刚接触过清洁架构。

我有一个usecase1类,该类通过构造函数注入注入了一个Repository实例:

 public class usecase1 {

    public final Repository repository;
    @Inject
    public usecase1(Repository repository) {
        this.repository = repository;
    }

    List<String> getlist(){
        return repository.list();
    }
}

在数据库层中,我有2种实现。一个用于本地,另一个用于Internet提取数据。

在匕首中,我为在线和离线创建2个带有@named注释的方法,并返回实现。这是模块代码:

 @Provides
@Singleton
@Named("Online")
Repository getRepository(){
  return new OnlineRepository();
}

@Provides
@Singleton
@Named("Offline")
Repository getRepository(){
    return new OfflineRepository();
}

@Provides
@Singleton
@Named("Offline")
Usecase1 getusecase1offline(@Named("Offline")Repository repository){
    return new usecase1(repository);
}

@Provides
@Singleton
@Named("Online")
Usecase1 getusecase1online(@Named("Online")Repository repository){
    return new usecase1(repository);

我的问题是如何注入适当的依赖关系。以及如何说出注入离线或在线用例的匕首。

android dagger-2
1个回答
1
投票

[没有看到我问过的其他问题,我只能提供太多的建议,这些都不等于猜测。换句话说,请帮助我。

在提供Module实例的usecase1中,您可能会执行以下操作:

@Module
class MyModule {
  // if you're provided qualified references for the usercase1 class
  // itself, then you could provide two implementations that use the same
  // qualifier as the Repository types they depend on (or choose another 

  @Provides @Named("Online")
  Repository provideOnlineUsecase1(@Named("Online") repository) {
    return new usecase1(repository);
  }

  @Provides @Named("Offline")
  Repository provideOfflineUsecase1(@Named("Offline") repository) {
    return new usecase1(repository);
  }

  // ...alternatively, if you're not providing qualified references of
  // usecase1 you can simply pick one. this might be the case if you're 
  // doing some manual testing and don't mind periodically rebuilding the
  // project switching between "Online" and "Offline":

  @Provides 
  Repository provideUsecase1(@Named("Offline") repository) {
    return new usecase1(repository);
  }
}

关键是您的合格Repository实例是通过在消费提供者方法中将它们引用为用相同命名的合格标识符注释的参数来绑定的。

换句话说,由于OfflineRepostiory具有@Named(“ Offline”)限定符,因此需要它的另一个提供程序可以通过将其声明为带有@Named(“ Offline)的Repository类型的参数来引用它“)。

顺便说一句……从广义上讲,似乎您的类型(usecase1Repository)具有通常只需要一个单例实例的性质,但是我在您的代码中看不到任何作用域修改器片段。

请记住,多分享一些有关您的问题可能会产生更好的反馈。希望我能有所帮助。

**更新**

根据您的评论,您似乎想知道如何基于动态计算的值(例如网络连接状态)在两个不同的Repository实现之间进行切换。在那种情况下,我可能会做这样的事情:

@Module
class MyModule {
  @Provides @Named("Online") 
  Repository provideOnlineRepository() {...}

  @Provides @Named("Offline") 
  Repository provideOfflineRepository() {...}

  @Provides
  Supplier<Boolean> provideIsConnectedSupplier() {...}

  @Provides
  Repository provideUseCase(
    Supplier<Boolean> isConnectedSupplier,
    @Named("Online") Repository onlineRepository,
    @Named("Offline") Repository offlineRepository) {

      return new usecase1(
        isConnectedSupplier, 
        onelineRepository, 
        offlineRepository);
  }
}

在此设置中,为usecase1提供了一个对象,可以对其进行查询以查看其是否具有网络连接,然后使用与结果相对应的Repository。这样的好处是您可以独立开发和测试所有组件,而您使用Dagger只是组装它们(而不是在模块中放置开关逻辑)。

从设计的角度来看,您可以做得比这更好(例如,使用流),但希望这足以激发一些想法。

© www.soinside.com 2019 - 2024. All rights reserved.