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

我有以下问题:

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

我怎么能这样做? 我是否必须创建多个模块才能执行此操作?

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

你有一个像这样的配置:

 @Override protected 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 services; public void doSomething(String selection) { Service service = services.get(selection); // do something with the service } 

您甚至可以使用自定义范围使用所选服务填充进样器。

我认为你真正想做的事情更像是这样的:

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

@ColinD有一个很好的方法。 我可能会建议

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

基本思路(在两个答案中)是如果你可以在构建注射器之前做出选择,你应该总是选择这样做。

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