我正在尝试将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注释)吗?
感谢
答案 0 :(得分:1)
一般来说,你的代码看起来很不错。在scaldi toProvider
或to
中获取一个函数作为参数,所以你总是绑定一个函数,该函数将在某个时候由库调用,以获得绑定依赖项的新实例。
在guice示例credentialsProvider
中,facebookProvider
,googleProvider
和twitterProvider
被注入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])