2

我有以下提供者:

class MyProvider implements Provider<T> {
  private final ClassX objectX;
  private String name;

  @Inject
  public MyProvider(ClassX objectX) {
    this.objectX = objectX
  }

  T get() {
    // uses name and objectX to provide an object of T
  }
}

我的绑定看起来像这样:

List<String> names;
for (String name : names) {
  bind(T.class).annotatedWith(Names.named(name))
    .toProvider(MyProvider.class)  // somehow set name in Provider
}

提供者的构造函数参数可从其他模块获得(并且注入器是从这个和那个其他模块创建的)。我无法弄清楚如何将该名称提供给提供者。理想的方法是将它也作为构造函数参数,在绑定中设置它的值。知道如何实现这样的目标吗?

4

3 回答 3

2

我终于做到了

class MyProvider implements Provider<T> {
  private ClassX objectX;
  private final String name;


  public MyProvider(String name) {
    this.name = name;
  }

  @Inject
  public setClassX(ClassX objectX) {
    this.objectX = objectX
  }

  T get() {
    // uses name and objectX to provide an object of T
  }
}

和绑定:

List<String> names;
for (String name : names) {
  MyProvider provider = new MyProvider(name);
  requestInjection(provider);
  bind(T.class).annotatedWith(Names.named(name))
    .toProvider(provider)  // somehow set name in Provider
}

requestInjection()方法是关键,它基本上将对象从同一个注入器中注入到带有注释的方法中@Inject

于 2013-09-20T12:12:06.277 回答
1

我不认为你能做到这一点。Guice 绑定应该始终是特定的;每个绑定键,它标识 Guice 在某个注入点必须注入什么,由一个类型和一个可能的注释组成:(Type, Optional<Annotation>) -> Implementation,你不能在这里省略类型,这是你真正想要实现的。

然而,Guice 能够绑定通配符类型,也就是说,可以绑定List<?>到某个提供者(使用TypeLiteral)。所以,我想,你应该能够创建一个类,比如说Cell<T>,它包装一个类型的对象T,并为Cell<?>. 但是,那么您应该只能注入Cell<?>,而不是像Cell<String>. 我不确定,也许 Guice 允许这种魔法,但可能性不大。

顺便说一句,您可以将任何参数传递给提供者构造函数,并通过字段或方法提供其托管依赖项。然后您可以绑定到该提供程序的实例:

bind(Smth.class).toProvider(new SmthProvider("whatever"));
于 2013-08-29T20:34:57.327 回答
0

您可以在提供程序中动态查找对象。但是,您必须提前知道您可能想要的所有名称。这将起作用:

class MyProvider implements Provider<T> {
  private final Class<T> objectX;
  private final String name;

  @Inject
  public MyProvider(Class<T> objectX, String name) {
    this.objectX = objectX
    this.name = name;
  }

  public T get() {
    // uses name and objectX to provide an object of T
  }

}

然后是绑定 - 每个名称都需要一个提供程序实例:

List<String> names = ...;
for (String name : names) {
  bind(SpecificType.class).annotatedWith(Names.named(name))
    .toProvider(new MyProvider<SpecificType>(SpecificType.class, name));
}

如果您正在缓存结果或类似的东西,您可能需要一些同步。

于 2013-09-10T19:02:17.283 回答