2016-07-18 36 views
1

在我吉斯模塊我有多個工廠像圖所示:如何使用Guice的AssistedInject工廠和服務加載器?

install(new FactoryModuleBuilder().implement(SportsCar.class,Ferrari.class).build(FerrariFactory.class)); 
install(new FactoryModuleBuilder().implement(LuxuryCar.class,Mercedes.class).build(MercedesFactory.class)); 

兩個工廠有以下創建方法,它需要一個輔助元素:

Ferrari create(@Assisted Element partsElement); 

Mercedescreate(@Assisted Element partsElement); 

在CarChooser類,我得到的情況下,法拉利或梅賽德斯的如下所示:

@Inject 
public CarChooser(FerrariFactory ferrariFactory , MercedesFactory mercedesFactory) 
{ 
     this.ferrariFactory = ferrariFactory; 
     this.mercedesFactory = mercedesFactory; 
} 

在相同的類:

if(type.equals("ferrari")) 
    ferrariFactory.create(partsElement); 
else if (type.equals("mercedes")) 
    mercedesFactory.create(partsElement); 
..... 
...... 

現在,我想要什麼我試圖使這個CarChooser類打開的擴展,但關閉修改。即如果我需要添加另一個工廠,我不應該將其聲明爲變量+將其添加到構造函數+爲相應的新類型添加另一個if子句。我打算在這裏使用ServiceLoader並聲明一個接口CarFactory,它將由所有工廠(如FerrariFactory,MercedesFactory等)實現,並且所有實現都有一個getCarType方法。但是我怎樣才能使用Service Loader調用創建方法?

ServiceLoader<CarFactory> impl = ServiceLoader.load(CarFactory.class); 

     for (CarFactory fac: impl) { 
      if(type.equals(fac.getCarType())) 
       fac.create(partsElement); 
     } 

是否正確的方式,如果它的工作(我甚至不知道這是否會工作)。還是有更好的方法來做同樣的事情嗎?

感謝這篇文章的第一條評論,我知道我想使用MapBinder。我寫了一個由FerrariFactory和MercedesFactory擴展的CarFactory。所以,我添加以下內容:

MapBinder<String, CarFactory> mapbinder = MapBinder.newMapBinder(binder(), String.class, CarFactory.class); 

    mapbinder.addBinding("Ferrari").to(FerrariFactory.class); 
    mapbinder.addBinding("Mercedes").to(MercedesFactory.class); 

但由於上面的代碼。要部分是抽象類,我得到一個初始化錯誤FerrariFactory不綁定到任何實現。我應該在這裏將其綁定到使用FactoryModuleBuilder聲明的正確輔助注入工廠?

+2

這是multibindings是。使用多功能裝置在模塊中綁定一個'Set '。 –

回答

0

因此,使用MapBinder和泛型是解決方案。

install(new FactoryModuleBuilder().implement(SportsCar.class,Ferrari.class).build(FerrariFactory.class)); 
    install(new FactoryModuleBuilder().implement(LuxuryCar.class,Mercedes.class).build(MercedesFactory.class)); 



    MapBinder<String, CarFactory<?>> mapbinder = MapBinder.newMapBinder(binder(), new TypeLiteral<String>(){}, new TypeLiteral<CarFactory<?>>(){}); 

    mapbinder.addBinding("ferrari").to(FerrariFactory.class); 
    mapbinder.addBinding("mercedes").to(MercedesFactory.class); 

這裏重要的是要注意的是,這似乎只有在吉斯3.0 + JDK 7,對於JDK 8,你需要吉斯4.0的支持!發現這個問題上https://github.com/google/guice/issues/904

希望有所幫助。

有關解決方案的更多細節:

http://crusaderpyro.blogspot.sg/2016/07/google-guice-how-to-use-mapbinder.html

相關問題