【问题标题】:Scala Play Guice using injector to manually inject a singleton class that has configuration injected into its constructorScala Play Guice 使用注入器手动注入一个已将配置注入其构造函数的单例类
【发布时间】:2017-01-18 01:41:14
【问题描述】:

使用 play 2.5 和 guice,我成功地将 applicationConfig 注入到一个单例类中,并在其中引用了一个配置变量,

trait TMongoFactory{
  val SERVER: String
  val PORT: Int
  val DATABASE: String
  val connection: MongoClient
  val collection: MongoDB
}

@Singleton
class MongoFactory @Inject()(val configuration: Configuration) extends TMongoFactory{
  val SERVER = "localhost"         
  val PORT = 27017
  val DATABASE = configuration.underlying.getString("connectionString")
  val connection = MongoClient(SERVER, PORT)  
  val collection = connection(DATABASE)
}


class MongoModule extends AbstractModule {
  def configure() = {
    bind(classOf[TMongoFactory]).to(classOf[MongoFactory])
  }
}    

然后我可以像这样将这个单例传递给存储库类

@Singleton
class MongoRemainingAllowanceRepository @Inject()(MongoFactory: TMongoFactory) extends RemainingAllowanceRepository{
  val context = MongoFactory.collection("remainingAllowance")
  def save(remainingAllowance: RemainingAllowance): Unit ={
    context.save(RemainingAllowance.convertToMongoObject(remainingAllowance))
  }

这一切都可以正常工作并且符合预期,但问题是我需要在测试套件中调用这个存储库,所以我不希望它必须接受任何参数(特别是注入的参数)。 所以我试着改变它,像这样在体内使用注射器

@Singleton
class MongoRemainingAllowanceRepository extends RemainingAllowanceRepository{
  val injector = Guice.createInjector(new MongoModule)
  val mongoFactory = injector.getInstance(classOf[TMongoFactory])

  val context = mongoFactory.collection("remainingAllowance")
  def save(remainingAllowance: RemainingAllowance): Unit ={
    context.save(RemainingAllowance.convertToMongoObject(remainingAllowance))
  } 

感觉它应该可以工作并且编译正常,但是在测试或运行时会抛出错误

Could not find a suitable constructor in play.api.Configuration. Classes
must have either one (and only one) constructor annotated with @Inject
or a zero-argument constructor that is not private. at
play.api.Configuration.class(Configuration.scala:173) while locating
play.api.Configuration

为这篇长文道歉,但我觉得我需要包括其中的大部分内容。 有谁知道为什么会在注射器上发生这种情况?我现在是否还需要手动绑定配置我引用了自定义模块?

任何帮助表示赞赏 谢谢 杰克

【问题讨论】:

  • 为什么不能在测试套件中提供参数?这是什么类型的测试?测试中是否正在运行 Guice/Play 应用?
  • 嗨,巴里,感谢您的回复,我不相信该应用程序正在作为测试的一部分运行,不,它是一个 Playspec,如果有办法加载应用程序并指导运行也可以,是的,我只是不知道如何。
  • 好的,我认为它应该可以发送一个要点,但要离开键盘一段时间......我在自己的应用程序中做了类似的事情

标签: scala playframework dependency-injection guice


【解决方案1】:

创建类时,您可以自己传递配置。假设您需要密钥 apiKey 及其值...

val sampleConfig = Map("apiKey" ->"abcd1234")
val mongoFactory = new MongoFactory(Configuration.from(sampleConfig))

【讨论】:

  • 巴里你是个传奇!我严重过度考虑这个问题,解决它的好方法,谢谢先生:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-16
相关资源
最近更新 更多