guice: runtime injection/binding at command line

人走茶凉 提交于 2020-01-01 15:05:43

问题


I have the following problem:

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

   public void doSomething() {
      service.invokeSelf(); 
   }

I have one module

bind(service).annotatedWith(Names.named("serviceA").to(ServiceAImpl.class);
bind(service).annotatedWith(Names.named("serviceB").to(ServiceBImpl.class);

Now my problem is I want to allow user to dynamically choose the injection on runtime base through command line parameter.

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

How could I do this? Do I have to create multiple modules just to do this?


回答1:


If you need to choose repeatedly at runtime which implementation to use the mapbinder is very appropriate.

You have a configuration like:

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

Then in your code just inject the map and obtain the right service based on your selection:

@Inject Map<String, Service> services;

public void doSomething(String selection) {
  Service service = services.get(selection);
  // do something with the service
}

You can even populate the injector with the selected service using custom scopes.




回答2:


I think what you actually want to do is something more like this:

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]));
  // ...
}



回答3:


@ColinD has a good approach. I might suggest

public static void main(String[] args) {
  Module m = "serviceA".equals(args[0]) ? new AServiceModule() : new BServiceModule();
  Injector injector = Guice.createInjector(m);
  // ...
}

The basic idea (in both answers) is if you can make your choices before the injector is built, you should always choose to do that.

As a matter of style, I like to keep the amount of logic inside a module to a minimum; but again, just a matter of style.



来源:https://stackoverflow.com/questions/7663618/guice-runtime-injection-binding-at-command-line

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!