0

我正在尝试从 Guice 转换为 Macwire 作为依赖注入框架。除了我遇到编译错误的这个剪影模块之外,一切都很好。底部错误。

Guice 中的工作模块:

  class SilhouetteModule @Inject()(environment: play.api.Environment, configuration: 
   Configuration) extends AbstractModule with ScalaModule {

  override def configure() = {
      val iamConfig = IAMConfiguration
        .fromConfiguration(configuration)
        .fold(throw _, identity)

      val htPasswdFile = File.apply(configuration.get[String]("file"))

      bind[IdentityService[User]].toInstance(SimpleIdentityService.fromConfig(iamConfig))
      bind[Silhouette[BasicAuthEnv]].to[SilhouetteProvider[BasicAuthEnv]]
      bind[RequestProvider].to[BasicAuthProvider].asEagerSingleton()
      bind[PasswordHasherRegistry].toInstance(PasswordHasherRegistry(new BCryptPasswordHasher()))
      bind[AuthenticatorService[DummyAuthenticator]].toInstance(new DummyAuthenticatorService)
      bind[AuthInfoRepository].toInstance(HtpasswdAuthInfoRepository.fromFile(htPasswdFile))
      bind[SecuredErrorHandler].to[RestHttpSecuredErrorHandler]
  }

    @Provides
    def provideEnvironment(identityService: IdentityService[User], authenticatorService: 
       AuthenticatorService[DummyAuthenticator], eventBus: EventBus, requestProvider: 
       RequestProvider): Environment[BasicAuthEnv] =
        Environment[BasicAuthEnv](
          identityService, 
          authenticatorService, 
          Seq(requestProvider), 
          eventBus
       )
   }
}

Macwire 中的等效尝试:

trait SilhouetteModule extends BuiltInComponents {
   import com.softwaremill.macwire._

   val iamConfig = IAMConfiguration
     .fromConfiguration(configuration)
     .fold(throw _, identity)

   val htPasswdFile = File.apply(configuration.get[String]("file"))

   lazy val identityService: IdentityService[User] =
     SimpleIdentityService.fromConfig(iamConfig)

   lazy val basicAuthEnv: Silhouette[BasicAuthEnv] = wire[SilhouetteProvider[BasicAuthEnv]]

   lazy val requestProvider: RequestProvider = wire[BasicAuthProvider]

   lazy val passwordHasherRegistry: PasswordHasherRegistry = PasswordHasherRegistry(
      new BCryptPasswordHasher())
   lazy val authenticatorService: AuthenticatorService[DummyAuthenticator] =
      new DummyAuthenticatorService
   lazy val authInfoRepo: AuthInfoRepository =
      HtpasswdAuthInfoRepository.fromFile(htPasswdFile)

   lazy val errorHandler: SecuredErrorHandler = wire[RestHttpSecuredErrorHandler]

   lazy val env: Environment[BasicAuthEnv] = Environment[BasicAuthEnv](
     identityService,
     authenticatorService,
     Seq(requestProvider),
     eventBus
   )
   def eventBus: EventBus
 }

Macwire 示例无法编译:我收到错误消息: Cannot find a value of type: [com.mohiva.play.silhouette.api.actions.SecuredAction] lazy val basicAuthEnv: Silhouette[BasicAuthEnv] = wire[SilhouetteProvider[BasicAuthEnv]]

抱歉,它有很多代码,但我认为并排比较会更有帮助。任何帮助都会很棒!

4

1 回答 1

1

MacWire 不会神奇地创建值 - 如果它需要构造一个值,它会查看构造函数采用的值,并且 - 如果通过查看范围内可用的所有值,它可以明确地找到构造函数的所有参数,宏创建代码new Class(resolvedArg1, resolvedArg2, ...)

所以

  • 所有这些值都必须在 Scope 中——它们可以由 MacWire 构造,或者是由某个 mixin 实现的抽象成员,但你仍然必须明确地写下来
  • 如果您在范围内有 2 个相同类型的值 - MacWire 无法生成代码,因为它如何知道要选择哪个值?(好吧,如果其中一个值比另一个值更接近“更接近”,但如果它们同样接近,则无法解决)

因此,如果您收到错误消息:

Cannot find a value of type: [com.mohiva.play.silhouette.api.actions.SecuredAction]

这意味着您没有声明任何类型的值com.mohiva.play.silhouette.api.actions.SecuredActioninSilhouetteModule或 in BuiltInComponents

如果这是另一个特征提供的东西,您可以在此处添加抽象声明

val securedAction: SecuredAction // abstract val

并在其他地方实现它(小心避免循环依赖!)。

于 2020-05-15T16:42:27.083 回答