2012-05-03 21 views
23

Zadeklarowałem obiekt, który zostanie zainicjowany przy starcie aplikacji. Chcę uzyskać do niego dostęp w kontrolerze, który jest częścią wtyczki. Chcę móc korzystać z tej wtyczki, ale nie mogę przejść przez pierwszą część - znajdowanie obiektu MyWebsocketConnection. Żaden z przykładów nie pokazuje, jak to zrobić. Nie chcę wprowadzać do kontrolera, ponieważ piszę wtyczkę (widziałem statyczne przykłady jak to zrobić gdzieś).Graj! 2.0 Scala - uzyskanie dostępu do obiektu globalnego

Global.scala, plugin aplikacji \ 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..."); 
    } 

} 

Mam zwyczaj kontroler plugin rejestrowania:

MyLogger.Scala, wtyczki kontrolerów aplikacji \ app \ \ MyLogger.scala

object MyLogger { 

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

} 

Tak więc, z Play! Aplikacja 2.0, która odwołuje się do wtyczki, mógłbym (prawdopodobnie) zrobić coś jak poniżej, ale nie mogę nawet ominąć części wcześniej:

MyFutureController.scala, kolejna gra! Aplikacja \ app \ sterowniki \ MyFutureController.scala

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

Odpowiedz

32

Istnieje również obejście # 3: przenieść globalnej klasy do pakietu i podać swoją nazwę pełną w application.conf pliku, tak jak poniżej:

globalny = my.packaged.Global

+0

To jest najlepsza odpowiedź. – vaughan

+2

Domyślną wartością jest 'application.global = ...'. Masz rację, powinno to być 'global = ...' bez 'aplikacji'. – samwize

3

Problemem jest to, że Global obiektów znajduje się w domyślnym pakiecie. A w Javie klas z pakietu domyślnego nie można odwoływać się z innych pakietów, są one dostępne tylko w tym samym pakiecie (domyślnie).

Widzę dwa obejścia tego problemu.

  1. Move MyWebsocketConnection pewnym nazwie pakietu (słownie config), więc może to być dostępne w aplikacji.

    object MyLogger { 
        def info(message: String) = { 
        config.MyWebsocketConnection.logger.send(message) 
        } 
    } 
    
  2. Przenieś całą swoją aplikację w jednym pakiecie (ale to jest dużo bólu)

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

    Następnie Global obiekt będzie rezyduje w foo pakietu i będzie dostępna wewnątrz aplikacji.

Powiązane problemy