2016-07-27 1 views
1

J'avais l'habitude d'obtenir la variable application.conf dans Play 2.4.x avec Play.current.configuration.getString('NAME_HERE'), et cela fonctionnait bien dans les objets de classe, objet et compagnon aussi.Comment obtenir la variable application.conf dans un objet en utilisant Scala et Play 2.5.x?

Maintenant, je suis en utilisant le jeu 2.5.4 avec Scala dans un nouveau projet, et je ne vais pas utiliser ce Play.current, parce qu'il est dépréciée, mais il existe une alternative en utilisant DI, comme ceci:

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

Cette injection DI fonctionne comme un charme en classe, mais dans ce projet, j'ai besoin d'obtenir la variable db.driver dans un objet? Et pour autant que je sache, avec un objet je ne peux pas utiliser DI.

Peut-être que l'utilisation de Guice aiderait?

Répondre

0

Vous pouvez faire

Play.current.configuration 

mais qui (probablement) ne sera plus possible avec le jeu 2.6.

Idéalement, cependant, vous devez passer la configuration en tant que paramètre à cette méthode de l'objet ou utiliser une classe au lieu d'un objet.

Ce que je fais somtimes de migrer « de l'objet à la classe »:

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 
    } 
} 

De cette façon, vous n'êtes pas casser le code existant alors que tous les utilisateurs de vos méthodes peuvent migrer lentement à l'aide de classes.

+0

@deprecated prend maintenant deux arguments :) et même si j'ajouté la version, en utilisant cela ne fonctionnera pas :) – elarib

+0

@elarib pourquoi pas? – rethab

1

Vous pouvez utiliser @Singleton classe annotée au lieu de object

trait Foo {} 

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

@Singleton fait la singleton.It de classe se sent peu gênant parce que Scala lui-même ont nativement la syntaxe object pour créer un singleton, mais cela est plus facile et probablement le meilleur solution à DI dans un singleton.

Vous pouvez également créer le singleton avec l'enthousiasme du code ci-dessous.

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

pour plus de détails Info, vous pouvez consulter Google Guice Wiki et Playframework site

EDIT

Comment vous l'appelez est exactement la même que la façon dont vous DI dans Playframework2.5.

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

Guice génère essentiellement nouvelle instance chaque fois que vous DI, Une fois que vous mettez @Singleton, Guice utiliser une seule instance à la place. DI est pour le couplage anti-haut. Ainsi, lorsque vous voulez utiliser une classe que vous avez définie à partir d'une autre classe, vous avez besoin de DI sinon les classes sont fortement couplées ce qui complique le codage de votre test unitaire.

FYI, vous pouvez les utiliser en dehors de Play avec cette technique.

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

+0

Et comment puis-je appeler ce singleton ??? – elarib

+0

@elarib a mis à jour la réponse. – suish