玩 2.5 剪影 4 - 带有 guice 的 DI

Posted

技术标签:

【中文标题】玩 2.5 剪影 4 - 带有 guice 的 DI【英文标题】:Play 2.5 Silhouette 4 - DI with guice 【发布时间】:2017-03-21 05:13:45 【问题描述】:

语言:斯卡拉; 框架:玩2.5; 库:Silhouette 4.0、Guice、scala-guice。

官方的 Silhouette 种子项目之一使用 guice 和 scala-guice (net.codingwell.scalaguice.ScalaModule) 编写 DI 配置。代码如下所示:

import net.codingwell.scalaguice.ScalaModule

class Module extends AbstractModule with ScalaModule

  /**
    * Configures the module.
    */
  def configure() 

    bind[Silhouette[MyEnv]].to[SilhouetteProvider[MyEnv]]
    bind[SecuredErrorHandler].to[ErrorHandler]
    bind[UnsecuredErrorHandler].to[ErrorHandler]
    bind[IdentityService[User]].to[UserService]

我想知道,如果没有来自 net.codingwell.scalaguice 库的魔法,这段代码会是什么样子。有人可以仅使用原始 guice 重写这些绑定吗?

另外我还有这个代码:

@Provides
  def provideEnvironment(
      userService: UserService,
      authenticatorService: AuthenticatorService[CookieAuthenticator],
      eventBus: EventBus
  ): Environment[MyEnv] = 
    Environment[MyEnv](
      userService,
      authenticatorService,
      Seq(),
      eventBus
    )
  

提前致谢。

【问题讨论】:

【参考方案1】:

感谢insan-e 指出正确的方向。这是显示如何使用 guice 注入通用实现的答案:

Inject Generic Implementation using Guice

因此,如果从方程中删除 scala-guice 库,绑定可以这样写:

import com.google.inject.AbstractModule, Provides, TypeLiteral
class Module extends AbstractModule 

  /**
    * Configures the module.
    */
  def configure() 
    bind(new TypeLiteral[Silhouette[MyEnv]]).to(new TypeLiteral[SilhouetteProvider[MyEnv]])

【讨论】:

【参考方案2】:

trait 上有介绍功能的描述,看这里:https://github.com/codingwell/scala-guice/blob/develop/src/main/scala/net/codingwell/scalaguice/ScalaModule.scala#L32

所以,在这种情况下,它会转化为如下内容:

class SilhouetteModule extends AbstractModule 

  def configure 
    bind(classOf[Silhouette[DefaultEnv]]).to(classOf[SilhouetteProvider[DefaultEnv]])
    bind(classOf[CacheLayer]).to(classOf[PlayCacheLayer])

    bind(classOf[IDGenerator]).toInstance(new SecureRandomIDGenerator())
    bind(classOf[PasswordHasher]).toInstance(new BCryptPasswordHasher)
    ...

【讨论】:

感谢您的回答,但我已经尝试过了,但由于某种原因它不起作用。我不知道为什么。如果我写这个:bind(classOf[Silhouette[DefaultEnv]]).to(classOf[SilhouetteProvider[DefaultEnv]]) 而不是这个:bind[Silhouette[MyEnv]].to[SilhouetteProvider[MyEnv]],我得到编译错误: CreationException: Unable to create injector,见如下错误: 1) com.mohiva.play.silhouette.api.Environment 不能作为key;它没有完全指定。在 com.mohiva.play.silhouette.api.SilhouetteProvider.(Silhouette.scala:103) 在 identity.Module.configure(Module.scala:47) (通过模块:com.google.inject.util.Modules$ OverrideModule -> identity.Module) 不能像那样绑定泛型类型。更像是这样:bind(new TypeLiteral[Silhouette[DefaultEnv]] ).to(classOf[SilhouetteProvider[DefaultEnv]]])

以上是关于玩 2.5 剪影 4 - 带有 guice 的 DI的主要内容,如果未能解决你的问题,请参考以下文章

带有熊猫的剪影分数的正确数据格式

Guice 4.1教程

使用请求数据的剪影授权

Guice源码学习基本原理

Play 2.4.0 功能测试中的 Specs2/Guice 问题

访问 R 中对象中的列表(剪影函数)