Java 重头戏2.5:模板中的依赖性注入

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

我试图在Scala模板中处理依赖注入对象(我使用的是基于Java的Play2.5)

我有一个模板系统,其中我有一个布局模板和最小的HTML基础,其中一个包含在几乎所有其他HTML模板中,这些模板正在构建HTML主体的其余部分

在模板中,我还包括带有“注销”按钮的顶部菜单,还有当前登录用户的名称

我有一个名为LocalAuthenticator的单例对象,它传递包含username的用户对象。到目前为止,我使用的是依赖注入,使用的是像这样的辅助Scala对象

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答案?