2016-07-27 7 views
1

Ich habe die application.conf Variable in Play 2.4.x mit Play.current.configuration.getString('NAME_HERE'), und es war gut in Klasse, Objekt und Companion-Objekt auch zu bekommen.Wie bekomme ich die application.conf-Variable in einem Objekt mit Scala und Play 2.5.x?

Jetzt

, ich bin mit Play-2.5.4 mit Scala in einem neuen Projekt, und ich werde dieses Play.current nicht verwendet werden, da es veraltet ist, aber es gibt eine Alternative DI verwendet wird, wie folgt aus:

class HomeController @Inject() (configuration: play.api.Configuration) extends Controller { 
    def config = Action { 
    Ok(configuration.underlying.getString("db.driver")) 
    } 
} 

Diese DI-Injektion funktioniert wie ein Charme in der Klasse, aber in diesem Projekt muss ich die Variable db.driver in einem Objekt bekommen? Und soweit ich weiß, kann ich mit einem Objekt DI nicht benutzen.

Vielleicht würde die Verwendung von Guice helfen?

Antwort

0

Sie können

Play.current.configuration 

jedoch tun, dass (wahrscheinlich) nicht mehr möglich, mit Play sein wird 2.6.

Idealerweise würden Sie die Konfiguration jedoch als Parameter an diese Methode des Objekts übergeben oder eine Klasse anstelle eines Objekts verwenden.

Was ich somtimes tun ‚in der Klasse von Objekt‘ zu migrieren:

class MyComponent @Inject() (config: Configuration) { 
    // here goes everything nice 
    def doStuff = ??? 
} 

object MyComponent { 
    @deprecated("Inject MyComponent") 
    def doStuff = { 
    val instance = Play.current.injector.instanceOf[MyComponent] 
    instance.doStuff 
    } 
} 

Auf diese Weise sind Sie nicht vorhandenen Code zu brechen, während alle Benutzer Ihrer Methoden langsam zur Verwendung von Klassen migrieren können.

+0

@deprecated jetzt zwei Argumente nimmt :) und auch wenn ich die Version hinzugefügt, dies mit funktioniert nicht :) – elarib

+0

@elarib warum nicht? – rethab

1

Sie können mit @Singleton kommentierte Klasse statt object

trait Foo {} 

@Singleton 
class FooImpl @Inject()(configuration: play.api.Configuration)) extends Foo { 
    //do whatever you want 
} 

@Singleton die Klasse singleton.It machen fühlt sich etwas umständlich, weil Scala selbst native Syntax object hat einen Singleton zu schaffen, aber dies ist die einfachste und wahrscheinlich am besten Lösung für DI in ein Singleton.

Sie können auch den Singleton eifrig wie der Code unten erstellen.

bind(classOf[Foo]).to(classOf[FooImpl])asEagerSingleton()

für mehr Detailinfo, können Sie Google Guice Wiki nachzuschlagen und Playframework site

EDIT

Wie man es nennen, ist genau das gleiche wie, wie Sie DI in Playframework2.5.

class BarController @Inject()(foo: Foo) extends Controller { 
    //Do whatever you want with Foo 
} 

Guice erzeugt grundsätzlich neue Instanz jedes Mal, wenn DI, Sobald Sie @Singleton setzen, Guice stattdessen nur eine Instanz verwenden.

DI ist für Anti-High-Kopplung.So wenn Sie eine Klasse verwenden möchten, die Sie aus einer anderen Klasse definiert haben, müssen Sie DI, andernfalls sind die Klassen stark gekoppelt, was es schwieriger macht, Ihren Komponententest zu programmieren.

FYI, Sie können sie außerhalb von Play mit dieser Technik verwenden.

Create an Instance of class which does DI via Playframework Guice Independently in Scala

+0

Und wie kann ich diesen Singleton ??? – elarib

+0

@elarib hat die Antwort aktualisiert. – suish

Verwandte Themen