Guice 中的空 Multibinder/MapBinder

ExF*_*Fed 3 java plugins dependency-injection guice

在使用GuiceMapBinder构建插件架构的过程中,使用Guice 3.0,我遇到了 GuiceCreationException在剥离所有模块时抛出 a 的问题,这是该应用程序中的一个可行配置。有没有办法让 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

dur*_*597 5

在 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();
}
Run Code Online (Sandbox Code Playgroud)

然后,当您创建注入器时,如果存在附加模块,那就太好了!添加它们。如果它们不存在,则不要添加它们。在你的课堂上,这样做:

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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

注意:你必须有空的MapBinder,否则Map如果没有可选模块,注入将不起作用。