我正在使用Guice和FactoryModuleBuilder。通常,只需定義工廠的界面就足夠了,Guice將自動注入實施。Guice,FactoryModuleBuilder,多個實現和泛型
但是,我掙扎的部分是工廠中的方法使用泛型。假設我有以下幾點。由接口定義的構造實例的基本類型。
interface Foo<T> {
T get();
}
並且Foo
接口的兩個實現由以下兩個類定義。
class FooA<T> implements Foo<T> {
@Inject
FooA(@Assisted Class<T> clazz, @Assisted String s) {...}
}
class FooB<T> implements Foo<T> {
@Inject
FooB(@Assisted Class<T> clazz, @Assisted Integer i) {...}
}
然後我有下面定義的工廠接口,使用兩個自定義綁定註釋,允許我使用多個實現。
interface FooFactory {
@A Foo<T> build(Class<T> clazz, String s);
@B Foo<T> build(Class<T> clazz, Integer i);
}
我已經嘗試了一些可能的解決方案,但除了一個迄今爲止工作。有效的解決方案是基本編寫我自己的FooFactory
的實現,如下所示。並且在模塊的configure
方法中,將接口綁定到實現; bind(FooFactory.class).to(FooFactoryImpl.class);
class FooFactoryImpl {
Foo<T> build(Class<T> clazz, String s) {
return new FooA(clazz, s):
}
Foo<T> build(Class<T> clazz, Integer i) {
return new FooB(clazz, i);
}
}
但是,我有這個解決方案的一個問題。這些實例不是由Guice創建的,因此我失去了Guice附帶的空檢查。這與我沒有這個問題的其他工廠完全不同。這意味着我必須爲Foo
的每個實現明確寫入空檢查。我想避免這種情況。
以下是我嘗試過的一些解決方案。
解決方案1:
FactoryModuleBuilder fmb = new FactoryModuleBuilder()
.implement(Foo.class, A.class, FooA.class)
.implement(Foo.class, B.class, FooB.class);
install(fmb.build(FooFactory.class));
解決方案2:
FactoryModuleBuilder fmb = new FactoryModuleBuilder()
.implement(TypeLiteral.get(Foo.class), A.class, TypeLiteral.get(FooA.class))
.implement(TypeLiteral.get(Foo.class), B.class, TypeLiteral.get(FooB.class));
install(fmb.build(TypeLiteral.get(FooFactory.class)));
的示例代碼可在GitHub(如果有人有興趣)。
您的FooA和FooB構造函數是否有任何注入的實例?他們應該嗎?我所看到的只有兩個@Assisted參數,這並不能解釋Guice在這裏的幫助。 – 2015-03-31 15:26:11
當工廠方法本身是通用的時,我不認爲輔助注入是有效的。但如果你讓它成爲'FooFactory'它可以工作。 –
2015-03-31 18:59:14
@JeffBowman,這是一個簡單的例子。儘管如此,無論構造函數是否有Guice自動注入的實例,您仍然希望Guice在自己的容器中管理這些新實例。另外,你得到免費的空檢查:) – ChristopherZ 2015-04-01 07:12:23