2013-08-29 102 views
0

提供一个值来提供,我有以下提供:在吉斯

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 
} 

构造函数参数提供商可从其他模块(和喷油器是从这个和其他模块创建的)。我无法弄清楚如何将该名称提供给提供者。理想的方法是将其作为构造函数参数,并在绑定中设置其值。任何想法如何能够实现这样的事情?

回答

1

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

但是,Guice能够绑定通配符类型,即可以将List<?>绑定到某个提供者(使用TypeLiteral)。所以,我想,你应该可以创建一个类,例如Cell<T>,它包装了一个T类型的对象,并为Cell<?>创建绑定。然而,那么你应该只能注入Cell<?>,而不是像Cell<String>这样的具体类型。我不确定,也许吉斯允许这样的魔法,但这不太可能。

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

bind(Smth.class).toProvider(new SmthProvider("whatever")); 
+0

如果托管依赖项由字段或方法提供,那么当您执行新的SmthProvider(“whatever”)时,将不会注入这些对象; – Aman

+0

嗯,我认为它会工作。那么,这是不可能知道的一切:) –

+1

@Aman实际上,'toProvider()'自动执行成员(场和setter)注入其参数。 –

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)); 
} 

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

0

我这样做最后

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注解的方法。