在使用Guice's MapBinderGuice 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的文档中,它说:


  支持从不同模块提供映射绑定。例如,可以使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注入将不起作用。

07-24 15:04