简体   繁体   English

将 Play Silhouette 模块从 Guice 转换为 Macwire 时出错

[英]Error converting Play Silhouette Module from Guice To Macwire

I am trying to convert from Guice to Macwire as a dependency injection framework.我正在尝试将 Guice 转换为 Macwire 作为依赖注入框架。 It is going fine apart from this Silhouette Module where I am getting a compilation error.除了我遇到编译错误的这个剪影模块之外,一切都很好。 Error at bottom.底部错误。

Working Module in Guice: 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
       )
   }
}

Equivalent attempt in Macwire: 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
 }

The Macwire example does not compile: I get an error: Cannot find a value of type: [com.mohiva.play.silhouette.api.actions.SecuredAction] lazy val basicAuthEnv: Silhouette[BasicAuthEnv] = wire[SilhouetteProvider[BasicAuthEnv]] Macwire 示例无法编译:我收到错误: Cannot find a value of type: [com.mohiva.play.silhouette.api.actions.SecuredAction] lazy val basicAuthEnv: Silhouette[BasicAuthEnv] = wire[SilhouetteProvider[BasicAuthEnv]]

Sorry its a lot of code but I thought a side-by-side comparison would be more helpful.抱歉,它有很多代码,但我认为并排比较会更有帮助。 Any help would be great!任何帮助都会很棒!

MacWire doesn't magically creates values - if it needs to construct a value, it looks what values are taken by the constructor and - if by looking at all values available in the scope it can unambiguously find all the parameters of the constructor, the macro creates code new Class(resolvedArg1, resolvedArg2, ...) . MacWire 不会神奇地创建值 - 如果它需要构造一个值,它会查看构造函数采用的值,并且 - 如果通过查看 scope 中可用的所有值,它可以明确找到构造函数的所有参数,即宏创建代码new Class(resolvedArg1, resolvedArg2, ...)

So所以

  • all of these values have to be in Scope - they can be constructed by MacWire, or be abstract members implemented by some mixin, but still you have to write them down explicitly所有这些值都必须在 Scope 中 - 它们可以由 MacWire 构造,或者是由某些 mixin 实现的抽象成员,但您仍然必须明确写下它们
  • if you have 2 values of the same type in scope - MacWire cannot generate the code because how it would know which value to pick?如果您在 scope 中有 2 个相同类型的值 - MacWire 无法生成代码,因为它如何知道要选择哪个值? (Well, if one of the values is in closer "closer" than the other it can, but if they are equally close it cannot be resolved) (好吧,如果其中一个值比另一个值更接近“更接近”,但如果它们同样接近,则无法解决)

So if you get the error:因此,如果您收到错误消息:

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

it means that you haven't declared any value of type com.mohiva.play.silhouette.api.actions.SecuredAction in SilhouetteModule nor in BuiltInComponents .这意味着您没有在SilhouetteModulecom.mohiva.play.silhouette.api.actions.SecuredAction中声明BuiltInComponents类型的任何值。

If this is something that is provided by another trait you can add abstract declaration here如果这是另一个特征提供的东西,您可以在此处添加抽象声明

val securedAction: SecuredAction // abstract val

and implement it somewhere else (be careful to avoid circular dependencies.).并在其他地方实现它(小心避免循环依赖。)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM