DI绑定到子类

时间:2014-11-23 17:52:18

标签: scala scaldi

我想知道是否可以使用以下语法绑定依赖项:

bind [Environment[User, Authenticator]] to FakeEnvironment[User, SessionAuthenticator](testUser)

(这是从测试中获得的,模块中的实际绑定稍微冗长一点)

其中SessionAuthenticator有以下签名:

case class SessionAuthenticator(val loginInfo : com.mohiva.play.silhouette.api.LoginInfo, ...)
    extends scala.AnyRef 
        with com.mohiva.play.silhouette.api.Authenticator 
        with scala.Product 
        with scala.Serializable {...}

Authenticator

 trait Authenticator extends scala.AnyRef {...}

但我得到的只是编译期间的以下堆栈跟踪:

[error] /home/mironor/projects/livrarium/test/controllers/CloudSpec.scala:22: overloaded method value to with alternatives:
[error]   [T <: com.mohiva.play.silhouette.api.Environment[services.User,com.mohiva.play.silhouette.api.Authenticator]](fn: => T)(implicit evidence$2: reflect.runtime.universe.TypeTag[T])scaldi.BoundHelper[T] <and>
[error]   (none: None.type)scaldi.BoundHelper[com.mohiva.play.silhouette.api.Environment[services.User,com.mohiva.play.silhouette.api.Authenticator]]
[error]  cannot be applied to (com.mohiva.play.silhouette.test.FakeEnvironment[services.User,com.mohiva.play.silhouette.impl.authenticators.SessionAuthenticator])
[error]       bind [Environment[User, Authenticator]] to FakeEnvironment[User, SessionAuthenticator](user)

通过这种方式,我可以在应用程序的Authenticator中选择Module只使用一次,然后将其注入:

implicit val env = inject[Environment[User, Authenticator]]

而不是:

implicit val env = inject[Environment[User, SessionAuthenticator]]

我有什么选择?

1 个答案:

答案 0 :(得分:1)

可以使用scaldi对此进行归档,但问题在于Environment的定义和使用方式。我假设(至少错误告诉我这个)Environment对它的两个类型参数都是不变的。这是问题所在,因为您希望将Environment[User, Authenticator]视为Environment[User, SessionAuthenticator]的超类。如果两个类型参数都定义为不变量,则不是这种情况。要解决此问题,您只需将Environment的第二个类型参数与+进行协变:

trait Environment[A, +B]

理论上它应该修复你显示的编译错误。