Scaldi绑定到提供者函数(带有注入键和值的Map参数)

时间:2014-07-02 20:04:04

标签: scala scaldi

我正在尝试将this repo从Guice移植到Scaldi。我在/app/utils/di/SilhouetteModule.scala (lines 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注释)吗?

感谢

1 个答案:

答案 0 :(得分:1)

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

在guice示例credentialsProvider中,facebookProvidergoogleProvidertwitterProvider被注入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 allows you to simplify it a little bit。< / p>

我还注入了所有播放配置,而不是直接使用Play - scaldi-play provides an integration with play configuration

最后,您还可以像这样提取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])