如何正确绑定同一服务的多个实现?

时间:2015-08-31 15:09:28

标签: scala dependency-injection guice

我有服务类:Service及其impls:RedisServiceImpl, DBServiceImpl

在我的应用程序中,几乎每个类都必须使用这两个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,我必须遍历所有类并用新名称替换"Redis" / "DB"。有更简单的方法吗?

我尝试在ServiceModule中创建常量,但是当我尝试将服务注入类时出现以下错误:

Error:(18, 34) annotation argument needs to be a constant; found: modules.ServiceModule.x
          , @Named(ServiceModule.x) redisService: Service
                             ^

以下是我要注入的课程:

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 ...
}

我得到了上面提到的错误。

2 个答案:

答案 0 :(得分:4)

这是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最终。

答案 1 :(得分:1)

如果我可以建议:重新思考你认识到的模式:责任链,也许是访客或装饰者。它们有多少实现被触发(ChoR在第一次成功时停止等,订单不受限制或具体)。我看到了不同的Guice方式来实现不同的模式。

PS。我不是设计模式的宗教phanatic,没有神圣的战争因为方法名称'next()'或其他等我可能有simmilar问题:2/3数据来源:JAR资源,文件系统,由Guice配置的数据库当地决定