Guice中的空Multibinder / MapBinder

时间:2015-04-28 18:25:56

标签: java plugins dependency-injection guice

在使用Guice's MapBinder使用Guice 3.0构建插件架构的过程中,我遇到了Guice在剥离所有模块时抛出CreationException的问题,这是一个该应用程序中的可行配置。有没有办法让Guice注入空Map?或者,通过扩展名,使用Multibinder

的空集

例如:

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

1 个答案:

答案 0 :(得分:3)

在MapBinder的文档中,它说:

  

支持从不同模块贡献地图绑定。例如,可以让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注入将无效。