我可以用匕首覆盖绑定吗?

时间:2013-04-22 19:50:29

标签: dependency-injection dagger

如果我有一个类的默认impl,并且确实定义了@Inject构造函数,那就太好了。系统选择它。

如果一个应用想要用子类覆盖那个默认的impl,我可以在它的模块中定义一个@Provides,并在我自己的代码中调用该子类的“new”,而dagger则使用那个impl(从我所知道的)到目前为止,这是有效的。)

但是,如果我想让dagger实例化那个子类,那么有没有办法在@Module中声明“override = true”?我喜欢没有override = true,所以在构建时的所有重复检查都给了我适当的警告。

这样做的一种方法当然是强制所有应用程序直接声明@Provides。这只会增加臃肿。

我之前使用过GIN(Guice for GWT),你可以通过.class引用定义你想要的类的绑定,但我没有看到任何类似的匕首。

1 个答案:

答案 0 :(得分:3)

现在,没有办法可以自由覆盖“默认绑定”,而不使用“覆盖”属性(更多用于测试而不是这个。)我们正在考虑如何进行默认绑定。

您可以考虑使用set绑定来执行此操作,方法如下:

@Module(...)
class MyModule {
  @Qualifier @interface OverridableFoo { }

  @Provides(type=SET_VALUES) @OverridableFoo Set<Foo> provideOverriddenFoo() {
    return new HashSet<Foo>(); // Empty set to ensure the Set is initialized.
  }

  @Provides Foo provideFoo(@OverridableFoo Set<Foo> Foo overriddenFoo) {
    switch (overriddenFoo.size()) {
      case 0: return new DefaultFooImpl();
      case 1: return overriddenFoo.iterator().next();
      default: throw new IllegalStateException("More than one overridden Foo Provided.");
    }
  }
}

然后,当你想要覆盖时,你只需要包含这个:

@Module(...)
class MyModule {
  @Provides(type=SET_VALUE) @OverridableFoo Foo provideBetterFoo() {
    return new MyAwesomeFoo();
  }
}

这不是一个好方法,因为它将应该是编译时错误移动到运行时,但是当我们尝试决定如何处理默认绑定时作为一个止损,我认为它是可行的