在guice中,有没有办法根据一些外部参数选择特定的绑定实现
例如:
public interface Service {
void sendMessage()
}
class EmailService implements Service {
public EmailService() { }
@Override
void sendMessage() {
println "Sending email..."
}
}
class SMSService implements Service {
public EmailService() { }
@Override
void sendMessage() {
println "Sending sms..."
}
}
class Client {
private Service service
@Inject
Client(Service service) {
this.service = service
}
public void send() {
service.sendMessage()
}
}
public class ServiceProvider implements Provider<Service> {
Service get() {
return new SMSService() //Select implementation here?
}
}
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(Service.class).toProvider(ServiceProvider.class).in(Scopes.SINGLETON)
}
}
public static void main(String...args) {
Injector injector = Guice.createInjector(new MyModule())
Client c = injector.getInstance(Client.class)
c.send()
}
在上面的例子中,我被迫选择在Provider get()方法中使用哪个提供程序。如果我想让它更具动态性,例如,根据用户偏好,有没有办法等待在运行时选择提供程序并让它注入它?
答案 0 :(得分:2)
对于这些问题,guice提供了MapBinder:
public class SnacksModule extends AbstractModule {
protected void configure() {
MapBinder<String, Snack> mapbinder
= MapBinder.newMapBinder(binder(), String.class, Snack.class);
mapbinder.addBinding("twix").toInstance(new Twix());
mapbinder.addBinding("snickers").toProvider(SnickersProvider.class);
mapbinder.addBinding("skittles").to(Skittles.class);
}
}
使用此绑定,现在可以注入Map:
class SnackMachine {
@Inject
public SnackMachine(Map<String, Snack> snacks) { ... }
}
您可以提前定义所有服务,然后通过配置值从地图中选择具体实例(或提供者)。