2017-01-04 7 views
0

У меня проблемы с пониманием базовой идеи инъекции зависимостей. (Я использую Play 2.5 с модулем play-slick). У меня есть класс Users, которому требуется подключение к базе данных.В чем смысл инъекции зависимостей, если вам все еще нужно передать аргумент?

package models 

@Singleton 
class Users @Inject() (dbConfigProvider: DatabaseConfigProvider) { 

    private val db = dbConfigProvider.get[JdbcProfile].db 

    private val users = TableQuery[UserTable] 

    private val setupAction = DBIO.seq(users.schema.create) 

    private val setupFuture: Future[Unit] = db.run(setupAction) 

    def getAll(): Future[Seq[User]] = setupFuture.flatMap(_ => 
    db.run(users.result) 
) 

    // More methods like the previous 
} 

Когда у меня есть мнение, что нужно, чтобы получить доступ к этим методам, я бы ожидать, что система впрыска топлива зависимости, чтобы заполнить dbConfigProvider зависимости для меня, как это.

package views 

class UserSearch { 

    def index(implicit ec: ExecutionContext): Future[String] = Future(
    (new Users).getAll().map(seq => seq.map(user => user.name).mkString(" ")) 
) 

} 

Однако это дает мне ошибку компиляции, и я вынужден сделать dbConfigProvider зависимость моего зрения и передать его в явном виде. В этом случае я, наконец, получаю dbConfigProvider от контроллера, вызывающего представление.

package views 

class UserSearch @Inject (dbConfigProvider: DatabaseConfigProvider) { 

    def index(implicit ec: ExecutionContext): Future[String] = Future(
    (new Users(dbConfigProvider)).getAll().map(seq => 
     seq.map(user => user.name).mkString(" ")) 
) 

} 

Я предполагаю, что я неправильно понял, как должна работать инъекция зависимости.

Так мои вопросы заключаются в следующем:

  1. Какой смысл использования @Inject() ключевое слово в моей модели Users тогда?

  2. Является ли мой дефект дизайна дефектным? Мне бы хотелось, чтобы Users и UserSearch были объектами, но тогда я не могу использовать им зависимость.

  3. В случае, если кто-либо знаком с Slick, это мой метод getAll() метод propper для работы с пятнами? Это даже правильный способ написать асинхронный код?

+0

'UserSearch' должен вводить« Пользователи », а не« DatabaseConfigProvider », которые« нужны пользователям ». Нет причин, по которым «UserSearch» должен знать об этом. –

+0

@MichaelZajac Спасибо, но тогда я бы каждый раз создавал экземпляр «новых пользователей» в методе Action моего контроллера? – rusins

+0

Нет, структура DI должна создавать все зависимости для вас. Если вам нужно использовать «Пользователи» в вашем контроллере, его следует ввести в контроллер. –

ответ

0

Благодаря комментариям @MichaelZajac, я изменил UserSearch быть объявлен так:

class UserSearch @Inject (users: Users) 

И я теперь мой контроллер настроить так:

class UsersController @Inject()(userSearch: UserSearch) extends Controller { 

    def index = Action.async { 
    implicit request => userSearch.index().map(Ok(_)) 
    } 

} 

Это ответ на мой первый вопрос и, увидев это в действии, также отвечает на мой второй вопрос. Я получаю SQL-ошибки, но, по крайней мере, мой проект компилируется.Позже я выяснил свой третий вопрос - оказывается, что нет причин для создания схемы таблиц, потому что в моем случае это делается файлами воспроизведения, поэтому я удалил часть setupFuture.flatMap, хотя она отлично работает с ней и не делает «Сделайте что-нибудь глупое, как создание таблицы дважды, или что-то еще, что вам может понадобиться при создании/запуске таблицы.

0

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

Например, если вы получаете экземпляр класса (MyExternalClass), которые будут ссылаться на внешние интерфейсы API, вы можете вместо этого послать подкласс (MyExternalSubClass extends MyExternalClass), который будет переопределять метод, который вызывает API, и просто возвращают предварительно сконфигурированный JSON

Есть также несколько преимуществ (и недостатки), перечисленные здесь (многие другие интересные статьи в Интернете):

+0

Почему бы не работать без инъекции зависимостей? – rusins