如何使用Dagger 2多重绑定注入字段?

时间:2016-02-23 23:03:12

标签: dependency-injection dagger

我尝试使用地图多重绑定来支持第三方扩展,但我无法理解它应该如何提供可扩展的基础架构。它似乎应该非常简单,但Dagger 2 documentation on multibindings实际上并未提供如何执行此操作的示例。我希望其他开发人员能够编写我自己提供的接口实现,然后将其无缝集成。

以下是一些示例代码,展示了我尝试做的事情:

// This is the interface that third parties can implement.
public interface FooService {
  public void run();
}

// This is the default implementation of the interface that I provide.
class DefaultFooImpl implements FooService {
  DefaultFooImpl() { ... }
  @Override public void run() { ... }
}

// Third parties would need to add their own modules to provide their
// implementations of FooService on different keys (right?).
@Module class DefaultImplModule {
  @Provides(type = MAP)
  @StringKey("default")
  static FooService provideDefaultImpl() {
    return new DefaultFooImpl();
  }
}

// PROBLEM! This won't work for third-party implementations, since I
// can't include their modules here because I don't know them.
@Component(modules = DefaultImplModule.class)
interface FooServiceComponents {
  Map<String, FooService> fooServices();
}

public class FooDispatcher {
  // PROBLEM! How do I actually inject this map?  Does this work?
  @Inject Map<String, FooService> fooServices;

  void callFooService(String whichService) {
    // whichService is any of the Strings in the combined services map.
    // For the default implementation, you'd pass in "default".
    this.fooServices.get(whichService).run();
  }
}

那么将这一切联系在一起的缺失部分实际上是什么呢?感谢。

1 个答案:

答案 0 :(得分:1)

以下是我使用的模式 - 必须在使用“组件”构建器时通过传递参数来配置模块。 强烈建议保留使用,只有在需要时 - 事情应该像你需要的那样简单,但不再是: - )

@Module
class ConfigurableModule {

    private IDependencyOne one;
    private IDependencyTwo two;
    ...

    ConfigurableModule() {

    }

    ConfigurableModule(IDependencyOne one, IDependencyTwo two, ...) {
        this.one = one;
        this.two = two;
    }


    @Provides IDependencyOne getIDependencyOne(MyIDependencyOneImpl impl) {
        return one == null ? impl : one;
    }

    @Provides IDependencyTwo getIDependencyTwo(MyIDependencyTwoImpl impl) {
        return one == null ? impl : one;
    }
}