Guice 中的空 Multibinder/MapBinder

Empty Multibinder/MapBinder in Guice

在使用 Guice's MapBinder, using 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);
    }
}

在 MapBinder 的文档中,它说:

Contributing mapbindings from different modules is supported. For example, it is okay to have both CandyModule and ChipsModule both create their own MapBinder, and to each contribute bindings to the snacks map. When that map is injected, it will contain entries from both modules.

所以,你要做的是,甚至不要在你的基本模块中添加条目。做这样的事情:

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 中,执​​行此操作:

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 注入将无法工作。