使用GoogleGuice在运行时注入依赖项

使用GoogleGuice在运行时注入依赖项,guice,Guice,我正在考虑在我的应用程序中使用Guice for DI,这样我就可以在运行时交换实现。下面提供了一个示例来说明该要求: 类验证引擎{ public void validate(ValidationService vs){} } 类client1u ValidationService实现ValidationService{} 类client2u ValidationService实现ValidationService{} 上面的一个实现应该绑定到基于客户端名称(比如Client1或Client2

我正在考虑在我的应用程序中使用Guice for DI,这样我就可以在运行时交换实现。下面提供了一个示例来说明该要求:

类验证引擎{
public void validate(ValidationService vs){}
}
类client1u ValidationService实现ValidationService{}
类client2u ValidationService实现ValidationService{}
上面的一个实现应该绑定到基于客户端名称(比如Client1或Client2)的运行时验证函数

我想这样更改ValidationEngine:

类验证引擎{
@注入
@命名(“vServicee”)验证服务vs;
public void validate(){
vs.validate()
}
}
上述方法的问题是@Named注释的参数是静态的;事实上,注释不接受运行时值。Guice中还有其他方法可以解决此类问题吗?

您可以尝试为每个
验证服务
实现创建自己的注入器:

Injector client1Injector=Injector.createChildInjector(新模块(){
@凌驾
公共作废配置(最终活页夹){
粘合剂
.bind(ValidationService.class)
.to(Client1_ValidationService.class);
}
});
ValidationEngine客户端1引擎=
client1Injector.getInstance(ValidationEngine.class)

但这意味着您必须以某种方式管理所有子注入器。

您可以通过GUI模块的构造函数将配置信息传递给它

伪代码:

main() { // your main method
    flags = parseFlags()
    injector = guice.createInjector(new MyModule(flags.validator))
}

MyModule { // your guice module
    constructor(validator): this.validator = validator;
    configure() {
        Class<ValidatorService> client_validator;
        if this.validator == KNOWN_CLIENT1:
            client_validator = Client1_ValidationService.class
        else:
            client_validator = Client2_ValidationService.class
        bind(ValidationService.class).to(client_validator);
    }
}
main(){//main方法
flags=parseFlags()
injector=guice.createInjector(新的MyModule(flags.validator))
}
MyModule{//您的GUI模块
构造函数(验证器):this.validator=验证器;
配置(){
类客户端验证程序;
如果this.validator==已知客户1:
client\u validator=Client1\u ValidationService.class
其他:
client\u validator=Client2\u ValidationService.class
绑定(ValidationService.class).to(客户机验证程序);
}
}
Guice对此提出了警告,因为它增加了测试的表面积

1)通过注射器直接注入,注射器名称如下:

@Inject
专用注射器;
公共验证服务getValidationServiceForClient(字符串clientName){
返回injector.getInstance(Key.get(ValidationService.class,Names.named(clientName));
}
2) 另一种方式:

公共类ValidationServiceProviderImpl实现ValidationServiceProvider{
@注入
@命名(“客户”)
私有验证服务客户端验证服务;
@注入
@命名(“客户B”)
私有验证服务客户端验证服务;
公共验证服务getValidationServiceForClient(字符串clientName){
开关(客户端名称){
案例“ClientA”:返回clientvalidationservice;
案例“ClientB”:返回clientBValidationService;
}
return null;//返回任何其他客户端的默认validationService
}
}
公共接口验证服务提供程序{
ValidationService GetValidationService循环客户端(字符串clientName);
}
配置:

Injector-Injector=Guice.createInjector(新抽象模块(){
受保护的void configure(){
绑定(ValidationService.class)
.annotatedWith(name.named(“ClientA”))
.to(ClientA_ValidationService.class);
绑定(ValidationService.class)
.annotatedWith(name.named(“ClientB”))
.to(ClientB_ValidationService.class);
绑定(ValidationServiceProvider.class)
.to(ValidationServiceProviderImpl.class);
}
});
使用提供者的示例:

ValidationServiceProvider validationServiceFactory=
getInstance(ValidationServiceProvider.class);
ValidationService客户端=
GetValidationServiceFactory.getValidationServiceForClient(“客户端”);
ValidationService客户端B=
GetValidationServiceFactory.getValidationServiceForClient(“客户端B”);
直接使用喷油器的示例:

ValidationService客户端=
getInstance(Key.get(ValidationService.class,Names.named(“ClientA”));
验证服务客户端B=
getInstance(Key.get(ValidationService.class,Names.named(“ClientB”));

这似乎没问题。我只是想澄清一下,如果我有5个客户,我最终会有5个注射器。将它们存储在HashMap中可能有助于使用客户端ID获取注射器。这是正确的方法吗?@giri_col似乎是这样。您必须为每个
ValidationService
实现保留注射器。诸如此类-