2016-07-27 3 views
1

Я использовал для получения переменной application.conf в Play 2.4.x с Play.current.configuration.getString('NAME_HERE'), и он работал хорошо в классе, объекте и объекте компаньона.Как получить переменную application.conf в объекте, используя Scala и Play 2.5.x?

Теперь я использую Play 2.5.4 с Scala в новом проекте, и я не буду использовать эту Play.current, потому что это не рекомендуется, но есть альтернатива с использованием DI, как это:

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

Этот DI Injection работает как шарм в классе, но в этом проекте мне нужно получить переменную db.driver в объекте? И насколько я знаю, с объектом я не могу использовать DI.

Возможно, использование Guice поможет?

ответ

0

Вы можете сделать

Play.current.configuration 

однако, что не будет (вероятно) больше не будет возможно с Play 2.6.

В идеале вы должны передать конфигурацию в качестве параметра этому методу объекта или использовать класс вместо объекта.

Что я Somtimes сделать, чтобы мигрировать «от объекта к классу»:

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

Таким образом, вы не нарушая существующий код, а все пользователи ваших методов может медленно мигрировать к использованию классов.

+0

@deprecated теперь принимает два аргумента :) и даже если я добавил версию, используя это не будет работать :) – elarib

+0

@elarib почему нет? – rethab

1

Вы можете использовать @Singleton аннотированный класс вместо object

trait Foo {} 

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

@Singleton делает класс singleton.It чувствует себя немного неловко, потому что сама Scala изначально имеют синтаксис object создать синглтон, но это самый простой и, вероятно, лучше всего решение DI в одноэлементное.

Вы также можете создать синглтон, как и код ниже.

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

для более подробной информации, Вы можете посмотреть Google Guice Wiki и Playframework site

EDIT

Как вы называете это точно так же, как, как вы DI в Playframework2.5.

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

Guice в основном создает новый экземпляр каждый раз, когда вы DI, как только вы поместите @Singleton, Guice использовать только один экземпляр вместо.

DI предназначен для защиты от высокой связи. Поэтому, когда вы хотите использовать класс, который вы определили из другого класса, вам необходимо выполнить DI, иначе классы будут сильно связаны, что затруднит код для тестирования вашего устройства.

FYI, вы можете использовать их вне игры с помощью этой техники.

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

+0

И как я могу назвать этот синглтон ??? – elarib

+0

@elarib обновил ответ. – suish