2015-04-28 53 views
2

在使用Guice's MapBinder使用Guice 3.0構建插件架構的過程中,我遇到了Guice拋出所有模塊時拋出CreationException的問題,這是在此應用程序中可行的配置。有沒有辦法讓Guice注入一個空的Map?或者,擴展名爲Multibinder的空集?Guice中的空Multibinder/MapBinder

例如:

interface PlugIn { 
    void doStuff(); 
} 

class PlugInRegistry { 
    @Inject 
    public PlugInRegistry(Map<String, PlugIn> plugins) { 
     // Guice throws an exception if OptionalPlugIn is missing 
    } 
} 

class OptionalPlugIn implements PlugIn { 
    public void doStuff() { 
     // do optional stuff 
    } 
} 

class OptionalModule extends AbstractModule { 
    public void configure() { 
     MapBinder<String, PlugIn> mapbinder = 
      MapBinder.newMapBinder(binder(), String.class, PlugIn.class); 
     mapbinder.addBinding("Optional").to(OptionalPlugIn.class); 
    } 
} 

回答

3

在用於MapBinder文檔,它說:

來自不同模塊的貢獻mapbindings被支撐。例如,可以同時使CandyModule和ChipsModule創建自己的MapBinder,並且每個貢獻綁定到零食圖。注入該映射時,它將包含來自兩個模塊的條目。

所以,你要做的是,甚至不要在你的基本模塊中添加條目。做這樣的事情:

private final class DefaultModule extends AbstractModule { 
    protected void configure() { 
    bind(PlugInRegistry.class); 

    MapBinder.newMapBinder(binder(), String.class, PlugIn.class); 
    // Nothing else here 
    } 
} 

interface PlugIn { 
    void doStuff(); 
} 

然後,當你創建你的注射器,如果附加模塊存在,太棒了!添加它們。如果它們不存在,則不要添加它們。在你的類,這樣做:

class PlugInRegistry { 
    @Inject 
    public PlugInRegistry(Map<String, PlugIn> plugins) { 
    PlugIn optional = plugins.get("Optional"); 
    if(optional == null) { 
     // do what you're supposed to do if the plugin doesn't exist 
    } 
    } 
} 

注:你必須有空MapBinder,或者如果不存在可選模塊的Map注入將無法正常工作。

+0

文檔中的語言比較隱祕。 MapBinder#newMapBinder的文檔暗示它純粹是一種工廠方法,並不表示任何副作用,例如構建綁定映射。 – ExFed

+0

@ExFed是的,文檔不是很好。你可以爭辯說,「有了這個綁定,一個'Map '現在可以被注入:」意味着它。說實話,我甚至都不知道如果我在自己的系統上做了一個測試用例,它到底會如何工作。我的第一次嘗試(沒有'DefaultModule'空綁定)失敗,然後我嘗試了這一點,它的工作。 – durron597

+0

我也碰巧知道這個構造會做一些事情,因爲我[剛纔在源代碼中已經看到了這一點](https://github.com/google/guice/blob/master/extensions/multibindings/src/ COM /谷歌/注入/ multibindings/MapBinder.java#L145) – durron597