Dagger:在Scoped模块中覆盖@ Provide-Method

时间:2014-12-24 15:27:36

标签: dependency-injection dagger

让我们假设以下情况。应用程序 main 中有一个全局模块AppModule,范围模块ScopedModule,一个类Main和一个类Foo变种。此外,还有一个 debug 变体,其中包含模块DebugAppModule,模块DebugScopedModule和类Bar。只有 debug 变体可能知道Bar

main 变体包含以下相关代码摘录。

@Module AppModule { /*..*/ }

@Module(injects=Main.class, addsTo=AppModule.class)
ScopedModule { @Provides Foo provideFoo() { return new Foo(); } }

class Main { scopedGraph = graph.plus(new ScopedModule(this)); }
class Foo { /*..*/ }

// In the entry point of the application
ObjectGraph.create(new AppModule());

debug 变体包含以下相关代码摘录。

@Module(addsTo=AppModule.class, overrides=true) DebugAppModule { /*..*/ }

@Module(injects=Main.class, addsTo=DebugAppModule.class, overrides=true)
DebugScopedModule { @Provides Foo provideFoo() { return new Bar(); } }

class Bar extends Foo { /*..*/ }

// In the entry point of the application
ObjectGraph.create(new AppModule(), new DebugAppModule());

我的研究和实验表明,无法覆盖范围模块中的@Provides - 方法,即plus模块时。请参阅示例How to Mock Dagger Activity Object Graphs。也就是说,在 debug 变体中,只要注入Foo,它仍然是Foo而不是Bar。这是有道理的,因为类Main具有与ScopedModule的固定依赖关系(请注意new)。

在我看来应该有一种方法来自己注入范围模块 - 元注入这样说:)。也就是说,AppModule可以为ScopedModule提供Main。问题是ScopedModule的构造函数需要Main的实例,因此AppModule需要保留Main的实例并且不会飞(例如{}}在特定于Android的上下文中,Main将是一个活动。)

那么在使用范围模块时,实现覆盖@Provides - 方法效果的最佳替代方法是什么?

1 个答案:

答案 0 :(得分:0)

在最新版本的Dagger中,不允许覆盖@Provided方法。

我找到了一个很好的解决方案here。感谢@vaughandroid

基本上, 在将模块提供到组件中时,可以覆盖方法。

MyComponent component = DaggerMyComponent.builder()
.appModule(new AppModule() {
  @Override public Foo provideFoo() { 
      return new Bar(); 
  }
})
.build();  

这对我有用,我想它将对您有用。