1

我正在尝试将此存储库从 Guice 移植到 Scaldi。我在/app/utils/di/SilhouetteModule.scala(第 60-65 行)的代码中堆叠:

  Map(
    credentialsProvider.id -> credentialsProvider,
    facebookProvider.id -> facebookProvider,
    googleProvider.id -> googleProvider,
    twitterProvider.id -> twitterProvider
  ),

这就是我现在的位置

class SilhouetteModule extends Module {

  bind[DelegableAuthInfoDAO[PasswordInfo]] to new PasswordInfoDAO
  bind[DelegableAuthInfoDAO[OAuth1Info]] to new OAuth1InfoDAO
  bind[DelegableAuthInfoDAO[OAuth2Info]] to new OAuth2InfoDAO
  bind[CacheLayer] to new PlayCacheLayer
  bind[HTTPLayer] to new PlayHTTPLayer
  bind[IDGenerator] to new SecureRandomIDGenerator
  bind[PasswordHasher] to new BCryptPasswordHasher
  bind[EventBus] to new EventBus


  bind[Environment[User, CachedCookieAuthenticator]] toProvider new Environment[User, CachedCookieAuthenticator](
    inject [UserService],
    inject [AuthenticatorService],
    // **this is where I don't know what to do**
    Map(
      credentialsProvider.id -> credentialsProvider,
      facebookProvider.id -> facebookProvider,
      googleProvider.id -> googleProvider,
      twitterProvider.id -> twitterProvider
    ),
    inject [EventBus]
  )
//... *Provider bindings below

我该怎么做才能像上面的代码一样注入 Map?

Scaldi 可以绑定到函数(如 Guice 中的 @Provides 注释)吗?

谢谢

4

1 回答 1

1

一般来说,您的代码看起来不错。在 scaldi 中toProviderto获取一个函数作为参数,因此您始终绑定一个函数,该函数将在某个时候由库调用,以获得绑定依赖项的新实例。

在 guice 示例credentialsProviderfacebookProvidergoogleProvidertwitterProvider被注入到provideEnvironment. 你需要在 scaldi 中做同样的事情:

binding toProvider {
  val credentialsProvider = inject [CredentialsProvider]
  val facebookProvider = inject [FacebookProvider]
  val googleProvider = inject [GoogleProvider]
  val twitterProvider = inject [TwitterProvider]

  new Environment[User, CachedCookieAuthenticator](
    inject [UserService],
    inject [AuthenticatorService],
    Map(
      credentialsProvider.id -> credentialsProvider,
      facebookProvider.id -> facebookProvider,
      googleProvider.id -> googleProvider,
      twitterProvider.id -> twitterProvider
    ),
    inject [EventBus])
}

所有这些依赖项都与 绑定toProvider,这意味着每次注入googleProvider时,例如,都会创建它的一个新实例。所以我首先将它们分配给val,然后使用它们创建Environment.

只是为了展示另一个绑定的示例,下面是绑定的方法GoogleProvider

binding toProvider new GoogleProvider(inject [CacheLayer], inject [HTTPLayer], OAuth2Settings(
  authorizationURL = inject [String] ("silhouette.google.authorizationURL"),
  accessTokenURL = inject [String] ("silhouette.google.accessTokenURL"),
  redirectURL = inject [String] ("silhouette.google.redirectURL"),
  clientID = inject [String] ("silhouette.google.clientID"),
  clientSecret = inject [String] ("silhouette.google.clientSecret"),
  scope = inject [String] ("silhouette.google.scope")))

我使用binding了代替,bind [...]因为在这种情况下,绑定的类型和您要绑定的实际值具有相同的类型,因此scaldi 允许您稍微简化一下

我也只是注入了所有的播放配置,而不是Play直接使用 - scaldi-play 提供了与播放配置的集成

最后,您还可以Map像这样提取它自己的绑定:

bind [Map[String, Provider]] toProvider {
  val credentialsProvider = inject [CredentialsProvider]
  val facebookProvider = inject [FacebookProvider]
  val googleProvider = inject [GoogleProvider]
  val twitterProvider = inject [TwitterProvider]

  Map(
    credentialsProvider.id -> credentialsProvider,
    facebookProvider.id -> facebookProvider,
    googleProvider.id -> googleProvider,
    twitterProvider.id -> twitterProvider
  )
}

Environment在这种情况下,绑定将如下所示:

binding toProvider new Environment[User, CachedCookieAuthenticator](
  inject [UserService],
  inject [AuthenticatorService],
  inject [Map[String, Provider]],
  inject [EventBus])
于 2014-07-03T00:14:22.250 回答