2012-05-03 33 views
23

Ich habe ein Objekt deklariert, das beim Programmstart instanziiert wird. Ich möchte darauf in einem Controller zugreifen, der Teil eines Plugins ist. Ich möchte in der Lage sein, dieses Plugin zu verwenden, aber ich kann nicht über den ersten Teil hinauskommen - das MyWebsocketConnection Objekt zu finden. Keines der Beispiele zeigt, wie dies zu tun ist. Ich möchte nicht in den Controller injizieren, weil ich ein Plugin schreibe (ich habe statische Beispiele gesehen, wie man das macht).Spielen! 2.0 Scala - Zugriff auf globales Objekt

Global.scala, Anwendung Plugin \ app \ Global.scala

object Global extends GlobalSettings { 

    object MyWebsocketConnection { 
    val logger = // return something that gets instantiated once, like websocket object for logging to ui 
    } 

    class MyWebsocketConnection { 
    import MyWebsocketConnection.logger 
    } 

    override def onStart(app: Application) { 
    Logger.info("Application has started..."); 
    } 

} 

Meine benutzerdefinierte Protokollierung-Plug-Controller:

MyLogger.Scala, Plugin-Anwendung \ app \ Controller \ MyLogger.scala

object MyLogger { 

    def info(message: String) = { 
    // THIS CAN'T BE FOUND ? 
    // MyWebsocketConnection.logger.send(message) 
    } 

} 

Also, von dem Spiel! 2.0 App, die das Plugin referenziert, würde ich (; wahrscheinlich) etwas tun wie unten, aber ich kann nicht einmal über den Teil vor dem:

MyFutureController.scala, ein anderes Spiel! application \ app \ Controller \ MyFutureController.scala

object MyFutureController extends Controller { 
    def someRandomMethod = Action { 
    // Custom logging 
    MyLogger.info("Here's my log message!"); 
    Ok("This documentation stinks!") 
    } 
} 

Antwort

32

Es gibt auch Abhilfe # 3: Ihre globale Klasse zu einem Paket bewegen und seine vollständig qualifizierten Namen in application.conf Datei angeben, etwa so:

global = my.packaged.Global

+0

Dies ist die beste Antwort. – vaughan

+2

Der Standardwert ist 'application.global = ...'. Du hast recht, es sollte 'global = ...' ohne die 'Anwendung' sein. – samwize

3

Das Problem ist, dass Ihre Global Objekte in Standardpaket befindet. Und in Java können Klassen vom Standardpaket nicht von anderen Paketen referenziert werden, sie sind nur innerhalb desselben Pakets zugänglich (Standard).

Ich sehe zwei Problemumgehungen dieses Problems.

  1. Verschieben MyWebsocketConnection zu einem gewissen Namen versehenes Paket (sagen wir config) so kann es in Ihrer Anwendung zugänglich sein.

    object MyLogger { 
        def info(message: String) = { 
        config.MyWebsocketConnection.logger.send(message) 
        } 
    } 
    
  2. Bewegen Sie die gesamte Anwendung in einzelnes Paket (aber es ist eine Menge Schmerz)

    foo 
        |--controllers 
        |--models 
        |--views 
        |--Global.scala 
    

    Dann Global Objekt in foo Paket befindet und wird innerhalb Anwendung zugänglich sein.