【问题标题】:How to pass a parameter to a shared dagger module?如何将参数传递给共享匕首模块?
【发布时间】:2022-01-05 20:49:22
【问题描述】:

我正在尝试让多个匕首模块共享一个公共模块,其中公共模块需要根据包含它的模块访问不同的字符串。

请注意,尽管在下面的示例代码中,我传递的是单个字符串(为简单起见),但实际上我想传递多个字符串

// The shared module
@Module()
public final class SharedModule {
  @Provides @Singleton
  public static SomeClass(String moduleSpecificString) {
    return new SomeClass(moduleSpecificString);
  }
}

// Two modules trying to use the shared module, but where each 
// module needs the shared module to be using a slightly different 
// parameter

@Module(includes = {SharedModule.class))
public final class ModuleA {
  @Provides @Singleton
  public static String moduleTextA() {
    return "ModuleA"
  }
}

@Module(includes = {SharedModule.class))
public final class ModuleB {
  @Provides @Singleton
  public static String moduleTextA() {
    return "ModuleB"
  }
}

目前我发现的两个潜在解决方案是:

  1. 改用@BindsInstance 在组件构建器中指定字符串

但这有将这些硬编码字符串移出模块的缺点(这意味着每个尝试仅构建模块的测试现在也必须声明这些字符串)

  1. 在 ModuleA 和 ModuleB 中使用 @IntoMap 将字符串插入到映射中。

这让我可以使用同一个映射来传递多个字符串,但似乎我放松了 dagger 的编译时检查,以确保我关心的映射中的每个键实际上都定义了一个值。

还有更好的选择吗?

【问题讨论】:

    标签: java dagger-2


    【解决方案1】:

    模块可以接受构造函数参数:这将要求您的 SharedModule 是一个类,并且任何与您的构造函数参数交互的东西都必须是非静态的。而不是使用@BindsInstance,您需要您的组件生成器/工厂来接受您创建的模块实例,因为在没有公共无参数构造函数的情况下,Dagger 甚至不会尝试。 (当然,这也允许您使用静态工厂方法、构建器或您选择的任何其他类型的接口。)

    @Module()
    public final class SharedModule {
      private final String moduleSpecificString;
    
      public SharedModule(String moduleSpecificString /*, ... */) {
        this.moduleSpecificString = moduleSpecificString;
        // ...
      }
    
      @Provides @Singleton
      public /* non-static */ SomeClass provideSomeClass() {
        return new SomeClass(moduleSpecificString);
      }
    }
    
    // elsewhere
    YourComponent yourComponent =
        YourComponent.builder()
            .sharedModule(new SharedModule("magic"))
            // ...
            .build();
    

    你也可以子类化:你可以让你的 SharedModule 抽象并让 ModuleA 和 ModuleB 从它继承,所以 ModuleA 和 ModuleB 有无参数的构造函数,用你的魔法字符串调用super。如果你走这条路,请谨慎行事:Dagger 的 Module.includes 的一个优点是它会删除包含的模块,因此如果 ModuleX 和 ModuleY 都安装了 ModuleZ,Dagger 不会抱怨 ModuleZ 出现多次。相比之下,如果 SharedModule 具有它公开的绑定,则 ModuleA 和 ModuleB 将或多或少地保证不能存在于同一组件中,因为该共享绑定将是 ModuleA 和 ModuleB 之间的必然重复绑定。 Dagger 在其testing guidebook page 中列出的模块子类化还有许多其他缺点。

    最后,如果您确实需要 ModuleA 和 ModuleB 与不同的魔术字符串共存,您可以考虑subcomponents for encapsulation。您可以定义一个包含 SharedModule 的 SharedComponent 并将特定的绑定传递回外部主图,而不是 ModuleA 和 ModuleB 公开相同的绑定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-30
      • 2017-12-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-02
      • 1970-01-01
      • 2011-04-04
      相关资源
      最近更新 更多