Java 重头戏2.5:模板中的依赖性注入
我试图在Scala模板中处理依赖注入对象(我使用的是基于Java的Play2.5) 我有一个模板系统,其中我有一个布局模板和最小的HTML基础,其中一个包含在几乎所有其他HTML模板中,这些模板正在构建HTML主体的其余部分 在模板中,我还包括带有“注销”按钮的顶部菜单,还有当前登录用户的名称 我有一个名为LocalAuthenticator的单例对象,它传递包含username的用户对象。到目前为止,我使用的是依赖注入,使用的是像这样的辅助Scala对象Java 重头戏2.5:模板中的依赖性注入,java,scala,playframework,dependency-injection,playframework-2.5,Java,Scala,Playframework,Dependency Injection,Playframework 2.5,我试图在Scala模板中处理依赖注入对象(我使用的是基于Java的Play2.5) 我有一个模板系统,其中我有一个布局模板和最小的HTML基础,其中一个包含在几乎所有其他HTML模板中,这些模板正在构建HTML主体的其余部分 在模板中,我还包括带有“注销”按钮的顶部菜单,还有当前登录用户的名称 我有一个名为LocalAuthenticator的单例对象,它传递包含username的用户对象。到目前为止,我使用的是依赖注入,使用的是像这样的辅助Scala对象 object LocalAuthent
object LocalAuthenticator {
private val cache = Application.instanceCache[core.security.LocalAuthenticator]
object Implicits {
implicit def localAuth(implicit application: Application): core.security.LocalAuthenticator = cache(application) }
}
然后,我能够使用这个构造从模板访问LocalAuthenticator
@import play.api.Play.current
@import scala.LocalAuthenticator.Implicits._
Logged in user is: @localAuth.getCurrentUser().name
这在2.4中是有效的,但是2.5抱怨play.api.play.current
由于使用静态上下文而被弃用
我知道正确的方法是将LocalAuthenticator注入控制器并将其传递给模板,但是这个对象应该存在于所有模板中,并且将它注入到每个控制器中是非常烦人的
有没有办法将单例类直接注入到模板中
我试图在helper对象中获取injector以获得singleton,但只有在我有Play
Application
object的情况下才能实现。而这只能使用DI检索。所以我在循环中运行:-)我认为您可以尝试在视图中使用ActionBuilder+隐式参数来实现您的需求。(我的回答基于我评论中的链接)
首先,您需要定义一个ActionBuild,根据请求从数据库或会话对象字段中提取当前用户,并将其添加到WrappedRequest的子类型中
//The subtype of WrapperRequest which now contains the username.
class UserRequest[A](val username: Option[String], request: Request[A]) extends WrappedRequest[A](request)
object UserAction extends
ActionBuilder[UserRequest] with ActionTransformer[Request, UserRequest] {
def transform[A](request: Request[A]) = Future.successful {
//request.session.get("username") in this example is the code to get the current user
//you can do db access here or other means.
new UserRequest(request.session.get("username"), request)
}
}
在视图上,您将定义UserRequest类型的隐式参数:
(message: String)(implicit h: UserRequest[AnyContent])
@main("Welcome to Play") {
//DISPLAY h.username
@h.username
}
最后,在您的控制器上定义一个requestHandler,它使用UserAction隐式地表示它的请求对象
// implicit user: UserRequest does the magic
def index = UserAction { implicit user: UserRequest[AnyContent] =>
Ok(views.html.index("Not Yet Implemented."))
}
希望这有帮助
关于ActionBuilder的更多信息:好的,找到了一个解决方案(或者解决方案) 使用这个页面,我创建了一个在应用程序启动时加载的助手模块
public class DIStaticModule extends AbstractModule {
protected void configure() {
requestStaticInjection(DIStaticFactory.class);
}
}
。。。然后是工厂班
public class DIStaticFactory {
@Inject
static LocalAuthenticator localAuthenticator;
@Inject
static LocalMessagingService localMessagingService;
@Inject
static OperationsMessagingService operationsMessagingService;
public static LocalAuthenticator getLocalAuthenticator() {
return localAuthenticator;
}
public static LocalMessagingService getLocalMessagingService() {
return localMessagingService;
}
public static OperationsMessagingService getOperationsMessagingService() {
return operationsMessagingService;
}
}
为了便于使用,我还创建了Scala对象,以便在模板中直接包含隐式变量
package core.di.scala
object DIStaticFactory {
implicit val operationsMessaging: OperationsMessagingService = core.di.DIStaticFactory.getOperationsMessagingService
implicit val localAuth: LocalAuthenticator = core.di.DIStaticFactory.getLocalAuthenticator
implicit val localMessaging: LocalMessagingService = core.di.DIStaticFactory.getLocalMessagingService
}
静态变量在Guice注入器启动时注入,如Guice文档中所述。一切正常
Scala模板中的用法很简单
@import core.di.scala.DIStaticFactory._
@if(localAuth.getCurrentUser().hasPermission("debug.tweaker")) { .. do something ... }
别忘了激活application.conf中的模块,也许这会有帮助:看起来很有希望。我正在使用Java Play,但是ActionBuilder也在那里可用,所以我将尝试一下。谢谢。我在模板、控制器和服务上的几乎所有注入都是由implicits或googleguice完成的:)我认为这将满足您的要求。如果您认为这是您问题的答案,请标记。谢谢。我不能完成这个。我有一个基于JAVA的游戏,所以我不能在控制器中使用Scala ActionBuild和隐式变量。在JavaAPI中似乎没有这样的东西。这里的Java API()中有一个动作组合,还包括“将对象传递给控制器”,但我如何将对象传递给视图?@LeoBufiBarrameda为什么要给Java问题一个scala答案?