Java guice:命令行上的运行时注入/绑定

Java guice:命令行上的运行时注入/绑定,java,command-line,binding,guice,code-injection,Java,Command Line,Binding,Guice,Code Injection,我有以下问题: @Inject MyClass(Service service) { this.service = service; } public void doSomething() { service.invokeSelf(); } 我有一个模块 bind(service).annotatedWith(Names.named("serviceA").to(ServiceAImpl.class); bind(service).an

我有以下问题:

   @Inject
   MyClass(Service service) {
      this.service = service;
   }

   public void doSomething() {
      service.invokeSelf(); 
   }
我有一个模块

bind(service).annotatedWith(Names.named("serviceA").to(ServiceAImpl.class);
bind(service).annotatedWith(Names.named("serviceB").to(ServiceBImpl.class);
现在我的问题是我想允许用户通过命令行参数在运行时动态选择注入

public static void Main(String args[]) {
   String option = args[0];
   ..... 
}

我怎么能这样做?我是否需要创建多个模块才能做到这一点?

我认为您真正想要做的是这样的:

public class ServiceModule extends AbstractModule {
  private final String option;

  public ServiceModule(String option) {
    this.option = option;
  }

  @Override protected void configure() {
    // or use a Map, or whatever
    Class<? extends Service> serviceType = option.equals("serviceA") ?
        ServiceAImpl.class : ServiceBImpl.class;
    bind(Service.class).to(serviceType);
  }
}

public static void main(String[] args) {
  Injector injector = Guice.createInjector(new ServiceModule(args[0]));
  // ...
}
公共类ServiceModule扩展了AbstractModule{
私有最终字符串选项;
公共服务模块(字符串选项){
this.option=选项;
}
@覆盖受保护的void configure(){
//或者用地图,或者别的什么

Class@ColinD有一个很好的方法。我可以建议

public static void main(String[] args) {
  Module m = "serviceA".equals(args[0]) ? new AServiceModule() : new BServiceModule();
  Injector injector = Guice.createInjector(m);
  // ...
}
基本的想法(在两个答案中)是,如果您可以在喷油器制造之前做出选择,您应该始终选择这样做


作为风格的问题,我喜欢将模块内部的逻辑量保持在最低限度;但同样,这只是风格的问题。

如果您需要在运行时反复选择使用哪个实现是非常合适的

您的配置如下所示:

@Override
protected void configure() {
  MapBinder<String, Service> mapBinder = MapBinder.newMapBinder(binder(), String.class, Service.class);
  mapBinder.addBinding("serviceA").to(ServiceAImpl.class);
  mapBinder.addBinding("serviceB").to(ServiceBImpl.class);
}
@覆盖
受保护的void configure(){
MapBinder MapBinder=MapBinder.newMapBinder(binder(),String.class,Service.class);
mapBinder.addBinding(“serviceA”).to(ServiceAImpl.class);
mapBinder.addBinding(“serviceB”).to(ServiceBImpl.class);
}
然后,在您的代码中,只需插入地图并根据您的选择获得正确的服务:

@Inject Map<String, Service> services;

public void doSomething(String selection) {
  Service service = services.get(selection);
  // do something with the service
}
@注入地图服务;
公共void doSomething(字符串选择){
服务=服务。获取(选择);
//对服务做些什么
}
您甚至可以使用所选服务填充喷油器