有没有办法在自定义提供程序中使用 Guice 初始化图而不是我自己构建实现
Is there a way to use Guice initialization graph in a custom provider instead of me constructing the implementations myself
我在 Java 中使用 Guice。
我想根据我代码的入口点更改接口的实现(主要class)
我想在每个入口点设置不同的System.property
并创建新的提供程序来初始化其中一个实现。
有没有办法使用 Guice 初始化图而不是我自己构建实现?
public class AltsMatcherProvider implements Provider<IAltsPairsMatcher> {
@Override
public IAltsPairsMatcher get() {
switch (System.getProperty(regressionType)) {
default:
case "regular": {
return new AltsPairsMatcherByName();
}
case "bidi": {
return new AltsPairsMatcherBySegments();
}
}
}
}
我在提供商中使用了@Inject
@Inject
public AltsMatcherProvider(ListUtils listUtils, SegmentsIdsChecker segmentsIdsChecker) {
this.listUtils = listUtils;
this.segmentsIdsChecker = segmentsIdsChecker;
}
@Override
public IAltsPairsMatcher get() {
final String routingType = System.getProperty(Constants.routingType);
if (routingType == null)
{
return new AltsPairsMatcherByName(listUtils, segmentsIdsChecker);
}
switch (routingType) {
default:
case "regular": {
return new AltsPairsMatcherByName(listUtils, segmentsIdsChecker);
}
case "bidi": {
return new AltsPairsMatcherBySegments(listUtils, segmentsIdsChecker);
}
}
}
}
这样做的传统方法是将特定实现的 Provider
注入到通用接口的 Provider
中:
public class AltsMatcherProvider implements Provider<IAltsPairsMatcher> {
@Inject Provider<AltsPairsMatcherByName> regularProvider;
@Inject Provider<AltsPairsMatcherBySegments> bidiProvider;
@Override
public IAltsPairsMatcher get() {
switch (System.getProperty(regressionType)) {
default:
case "regular": {
return regularProvider.get();
}
case "bidi": {
return bidiProvider.get();
}
}
}
}
(或者使用构造函数注入而不是 @Inject
ed 字段;我是通过移动设备回答的,所以只使用了最少的代码)
提供程序在创建时被注入,因此您可以请求 Injector
或 Provider
类型 AltsPairsMatcherByName
和 AltsPairsMatcherBySegments
.
但是...我不认为自定义 Provider
是解决此问题的正确方法。这听起来像是 custom annotations/@Named OR a variant on the Robot Legs.
的情况
在这种情况下,我将实现两个独立的模块:
public void configure() {
bind(IAltsPairsMatcher.class).to(AltsPairsMatcherByName.class);
}
...
public void configure() {
bind(IAltsPairsMatcher.class).to(AltsPairsMatcherBySegments.class);
}
然后根据系统属性或命令行标志选择要安装的模块:
class ParentModule {
public void configure() {
switch (System.getProperty(Constants.routingType)) {
case NAME:
install(new ByNameModule());
break;
case SEGMENT:
install(new BySegmentsModule());
break;
}
}
}
这保持了很好的 属性 您的对象图可以相对于注入器静态解析,并且绝对不会在运行时更改。只需检查您的模块,您就应该能够分辨出特定实现的来源。这在 Guice 错误消息习语中进行了编码,它向您展示了从原始父级一直到绑定的模块链。您也可以只在 switch 语句中内联绑定,重要的是一切都在注入器创建时解决。
我在 Java 中使用 Guice。
我想根据我代码的入口点更改接口的实现(主要class)
我想在每个入口点设置不同的System.property
并创建新的提供程序来初始化其中一个实现。
有没有办法使用 Guice 初始化图而不是我自己构建实现?
public class AltsMatcherProvider implements Provider<IAltsPairsMatcher> {
@Override
public IAltsPairsMatcher get() {
switch (System.getProperty(regressionType)) {
default:
case "regular": {
return new AltsPairsMatcherByName();
}
case "bidi": {
return new AltsPairsMatcherBySegments();
}
}
}
}
我在提供商中使用了@Inject
@Inject
public AltsMatcherProvider(ListUtils listUtils, SegmentsIdsChecker segmentsIdsChecker) {
this.listUtils = listUtils;
this.segmentsIdsChecker = segmentsIdsChecker;
}
@Override
public IAltsPairsMatcher get() {
final String routingType = System.getProperty(Constants.routingType);
if (routingType == null)
{
return new AltsPairsMatcherByName(listUtils, segmentsIdsChecker);
}
switch (routingType) {
default:
case "regular": {
return new AltsPairsMatcherByName(listUtils, segmentsIdsChecker);
}
case "bidi": {
return new AltsPairsMatcherBySegments(listUtils, segmentsIdsChecker);
}
}
}
}
这样做的传统方法是将特定实现的 Provider
注入到通用接口的 Provider
中:
public class AltsMatcherProvider implements Provider<IAltsPairsMatcher> {
@Inject Provider<AltsPairsMatcherByName> regularProvider;
@Inject Provider<AltsPairsMatcherBySegments> bidiProvider;
@Override
public IAltsPairsMatcher get() {
switch (System.getProperty(regressionType)) {
default:
case "regular": {
return regularProvider.get();
}
case "bidi": {
return bidiProvider.get();
}
}
}
}
(或者使用构造函数注入而不是 @Inject
ed 字段;我是通过移动设备回答的,所以只使用了最少的代码)
提供程序在创建时被注入,因此您可以请求 Injector
或 Provider
类型 AltsPairsMatcherByName
和 AltsPairsMatcherBySegments
.
但是...我不认为自定义 Provider
是解决此问题的正确方法。这听起来像是 custom annotations/@Named OR a variant on the Robot Legs.
在这种情况下,我将实现两个独立的模块:
public void configure() {
bind(IAltsPairsMatcher.class).to(AltsPairsMatcherByName.class);
}
...
public void configure() {
bind(IAltsPairsMatcher.class).to(AltsPairsMatcherBySegments.class);
}
然后根据系统属性或命令行标志选择要安装的模块:
class ParentModule {
public void configure() {
switch (System.getProperty(Constants.routingType)) {
case NAME:
install(new ByNameModule());
break;
case SEGMENT:
install(new BySegmentsModule());
break;
}
}
}
这保持了很好的 属性 您的对象图可以相对于注入器静态解析,并且绝对不会在运行时更改。只需检查您的模块,您就应该能够分辨出特定实现的来源。这在 Guice 错误消息习语中进行了编码,它向您展示了从原始父级一直到绑定的模块链。您也可以只在 switch 语句中内联绑定,重要的是一切都在注入器创建时解决。