2011-06-16 72 views
5

我有一个工厂,我喜欢使用吉斯重新实现:实现参数化工厂吉斯

enum MyObjects { OBJECT1, OBJECT2, ... } 
class Object1 implements SomeInterface { ... } 
class Object2 implements SomeInterface { ... } 
... 
class Factory { 
    public static SomeInterface createObject(MyObjects obj) { 
    switch (obj) { 
    case OBJECT1: return new Object1(); 
    case OBJECT2: return new Object2(); 
    ... 
    } 
    } 

有没有实现它的简单方法? 像Provider.get(参数)和使用绑定来定义在每种情况下应该使用哪个对象?

回答

5

您在这里有几个选项。

1.因为您使用enum实现之间进行区分,则有一个可以与他们自己的绑定定义每个实施方式中的一个有限数量,只要你注射

public @interface SomeInterfaceKind { 
    MyObjects value(); 
} 

过程中使用的注释在Module

bind(SomeInterface.class) 
    .annotatedWith(new SomeInterfaceKindImpl(MyObjects1.OBJECT1) 
    .to(Object1.class); 
... 

然后在类注射:

@Inject void setSomeInterface(
    @SomeInterfaceKind(MyObjects.OBJECT1) SomeInterface object) {...} 

在这里,你必须定义SomeInterfaceKindImpl类,它实现SomeInterfaceKind(是的,这可能延长的注释!)更多详情,看看Named如何在吉斯实施。

2.您还可以使用吉斯MapBinder如下(我觉得很容易实现)

在你的模块:

MapBinder.newMapBinder(MyObjects.class, SomeInterface.class) 
    .addBinding(MyObjects.OBJECT1).to(Object1.class); 
MapBinder.newMapBinder(MyObjects.class, SomeInterface.class) 
    .addBinding(MyObjects.OBJECT2).to(Object2.class); 

然后在注射方法:

@Inject void setSomeInterface(Map<MyObjects, SomeInterface> map) { 
    SomeInterface object1 = map.get(MyObjects.OBJECT1); 
    ... 
} 
+0

感谢您的答复,你可以使用工厂英寸 据我所知,第一个选项在编译时更为合适,实际的类是已知的,而第二个选项允许在运行时决定使用哪个实现。 – 2011-06-20 12:35:11

4

您也可以使用辅助注射

public interface Factory { 

    public Object1 createObject1(String param1); 
    public Object2 createObject2(Date param2); 

} 


public class Object1 { 
    @AssistedInject 
    public Object1(String param1) { 
      // do something 
    } 
} 

public class Object2 { 
    @AssistedInject 
    public Object2(Dateparam2) { 
     // do something 
    } 
} 

然后你的模块

install(new FactoryModuleBuilder() 
    .implement(Object1.class, Object1.class) 
    .implement(Object2.class, Object2.class) 
    .build(Factory.class)); 

那么无论你需要它

@Inject 
private Factory factory;