Guice:注入一个字符串的ArrayList
我试图在Guice的帮助下注入String
的ArrayList
。 我想显示一个带有许多RadioButtons的面板(例如),用户可以选择一些要激活的服务。
选择后,我想获取所选服务的所有名称并将其添加到列表中,并将此列表注入负责创建服务的经理。 这是一个例子:
public class UIProviderModule extends ProviderServiceModule { private ArrayList requestedServices; public UIProviderModule(ArrayList requestedServices) { this.requestedServices = requestedServices; } @Override protected void configure() { bindConstant().annotatedWith(Names.named(Constants.REQ_SERVICES)).to(requestedServices); bind(IParser.class).to(UIParser.class); super.configure(); } }
我看过很多关于Multibindings和提供者的post,但我不明白这对我有什么帮助。 我只想检索名称,因为我不使用必须绑定到接口的类。 我错过了什么吗?
注意:我知道这可能不是使用Guice的好方法,因为我将列表绑定到Module
。
我认为你误解了模块应该如何工作。
模块不创建对象 ,模块定义了在需要时如何 创建对象的 规则。
MapBinder提供帮助的原因是您将在单选按钮列表中定义所有服务,然后使用注入的映射来激活所需的服务。
这里有一些代码来说明我的意思:
public class ServiceModule extends AbstractModule { protected void configure() { MapBinder mapbinder = MapBinder.newMapBinder(binder(), String.class, Service.class); mapbinder.addBinding("service1").to(Service1.class).in(Singleton.class); mapbinder.addBinding("service2").to(Service2.class); // Define ALL the services here, not just the ones being used. // You could also look this up from a ClassLoader or read from a configuration file if you want } }
然后,将MapBinder注入您的ServiceManager
类 – 这不是一个模块:
public class ServiceManager { private final Map serviceMap; @Inject public ServiceManager(Map serviceList) { for(String serviceName : serviceList) { serviceMap.get(serviceName).start(); } } }
这很容易做Guice:
bind(new TypeLiteral>() {}) .annotatedWith(Names.named(Constants.REQ_SERVICES)) .toInstance(requestedServices);
请注意,为了在不使用Java擦除generics的情况下绑定List
,可以创建一个短命的匿名内部类型(TypeLiteral的子类,其中包含空体{}
)。 你也使用toInstance
。
使模块采用用于绑定的参数没有任何问题,而且当在一个地方容易收集所有绑定时,我更喜欢使用Multibindings。
请注意,您接受的ArrayList
是可变的,因此如果您在多个位置注入此列表,则一个消费者可以为其他所有人永久更改列表。 使用Guava的ImmutableList.copyOf(list)
或Collections.unmodifiableList(list)
可能更有意义(尽管如果模块创建者稍后更改传入列表,后者仍会让列表更改)。
关于您提出的应用程序生命周期,请记住Guice的绑定应该在创建注入器后保持或多或少保持不变。 您描述的生命周期可能有两个方面:
- 在没有Guice帮助的情况下显示您的对话框,然后使用所选选项创建一个Injector
- 注入所有选项的
List
,显示对话框,然后传递列表 - 使用所有选项注入
List
,显示对话框,然后创建包含所选选项列表的子注入器
但是,所有这些都是可行的,具体取决于您希望完整列表和选定列表在您的应用程序中的可访问性。