如何正确绑定同一服务的多个实现?
How do I correctly bind multiple implementations of the same service?
我有服务 class:Service
及其含义:RedisServiceImpl, DBServiceImpl
.
在我的应用程序中,几乎每个 class 都必须使用这两个 impl 来更新字段。我想使用 Guice 来注入这些服务。
class ServiceModule extends AbstractModule with ScalaModule {
override def configure(): Unit = {
bind[Service].annotatedWith(Names.named("Redis")).toInstance(new RedisServiceImpl("localhost"))
bind[Service].annotatedWith(Names.named("DB")).toInstance(new DBServiceImpl("some external host"))
}
}
这个问题是,如果我们离开 redis/db,我将不得不搜索所有 classes 并替换 "Redis"
/"DB"
与新名称。有更简单的方法吗?
我尝试在 ServiceModule 中创建常量,但是当我尝试将服务注入 class 时出现以下错误:
Error:(18, 34) annotation argument needs to be a constant; found: modules.ServiceModule.x
, @Named(ServiceModule.x) redisService: Service
^
这是我要注入的 classes:
class Poller @Inject()(
@Named("PollService") pollService: PollService[List[ChannelSftp#LsEntry]]
, @Named("Redis") redisStatusService: StatusService
, @Named("DB") dynamoDbStatusService: StatusService
) {
... methods ...
}
如果我尝试过:
class Poller @Inject()(
@Named(ServiceModule.x) pollService: PollService[List[ChannelSftp#LsEntry]]
, @Named("Redis") redisStatusService: StatusService
, @Named("DB") dynamoDbStatusService: StatusService
) {
... methods ...
}
我收到上面提到的错误。
这是问题所在,在 Poller
中不是您的 Guice 模块:
@Named(ServiceModule.x) pollService: PollService[List[ChannelSftp#LsEntry]]
注释参数必须是常量,如错误消息中所述:
Error:(18, 34) annotation argument needs to be a constant; found: modules.ServiceModule.x
, @Named(ServiceModule.x) redisService: Service
您似乎遇到了与此问题相同的问题:Best practice for use constants in scala annotations;尝试使 ServiceModule.x
成为最终版本。
如果我可以建议:重新考虑您实现的模式:责任链,也许是访问者或装饰者。它们的不同之处在于触发了多少实现(ChoR 在第一次成功时停止等,命令不受限制或具体)。我看到了不同的 Guice 方法来实现不同的模式。
PS。我不是设计模式的宗教狂热者,也不是因为方法名称 'next()' 或其他原因而发生的圣战。我可能有类似的问题:2/3 数据源:JAR 资源、文件系统、Guice 配置的数据库本地决策
我有服务 class:Service
及其含义:RedisServiceImpl, DBServiceImpl
.
在我的应用程序中,几乎每个 class 都必须使用这两个 impl 来更新字段。我想使用 Guice 来注入这些服务。
class ServiceModule extends AbstractModule with ScalaModule {
override def configure(): Unit = {
bind[Service].annotatedWith(Names.named("Redis")).toInstance(new RedisServiceImpl("localhost"))
bind[Service].annotatedWith(Names.named("DB")).toInstance(new DBServiceImpl("some external host"))
}
}
这个问题是,如果我们离开 redis/db,我将不得不搜索所有 classes 并替换 "Redis"
/"DB"
与新名称。有更简单的方法吗?
我尝试在 ServiceModule 中创建常量,但是当我尝试将服务注入 class 时出现以下错误:
Error:(18, 34) annotation argument needs to be a constant; found: modules.ServiceModule.x
, @Named(ServiceModule.x) redisService: Service
^
这是我要注入的 classes:
class Poller @Inject()(
@Named("PollService") pollService: PollService[List[ChannelSftp#LsEntry]]
, @Named("Redis") redisStatusService: StatusService
, @Named("DB") dynamoDbStatusService: StatusService
) {
... methods ...
}
如果我尝试过:
class Poller @Inject()(
@Named(ServiceModule.x) pollService: PollService[List[ChannelSftp#LsEntry]]
, @Named("Redis") redisStatusService: StatusService
, @Named("DB") dynamoDbStatusService: StatusService
) {
... methods ...
}
我收到上面提到的错误。
这是问题所在,在 Poller
中不是您的 Guice 模块:
@Named(ServiceModule.x) pollService: PollService[List[ChannelSftp#LsEntry]]
注释参数必须是常量,如错误消息中所述:
Error:(18, 34) annotation argument needs to be a constant; found: modules.ServiceModule.x
, @Named(ServiceModule.x) redisService: Service
您似乎遇到了与此问题相同的问题:Best practice for use constants in scala annotations;尝试使 ServiceModule.x
成为最终版本。
如果我可以建议:重新考虑您实现的模式:责任链,也许是访问者或装饰者。它们的不同之处在于触发了多少实现(ChoR 在第一次成功时停止等,命令不受限制或具体)。我看到了不同的 Guice 方法来实现不同的模式。
PS。我不是设计模式的宗教狂热者,也不是因为方法名称 'next()' 或其他原因而发生的圣战。我可能有类似的问题:2/3 数据源:JAR 资源、文件系统、Guice 配置的数据库本地决策