Как я могу сделать вставленную зависимость WireBox доступной для метода конструктора?

В этом примере у меня есть объект модели под названием test.cfc которая имеет зависимость testService.cfc,

test имеет инъекцию WireBox testService через декларацию о недвижимости. Объект выглядит так:

component {

     property name="testService" inject="testService";

     /**
     *  Constructor
     */
     function init() {

         // do something in the test service
         testService.doSomething();

         return this;

     }

 }

Для справки, testService имеет единственный метод с именем doSomething() который выводит некоторый текст:

component
     singleton
{

     /**
     *  Constructor
     */
     function init() {

         return this;

     }


     /**
     *  Do Something
     */
     function doSomething() {

         writeDump( "something" );

     }

 }

Проблема в том, что WireBox, похоже, не вводит testService пока после конструктора init() метод пожаров. Итак, если я запускаю это в моем обработчике:

prc.test = wirebox.getInstance(
     name = "test"
);

Я получаю следующее сообщение об ошибке: Error building: test -> Variable TESTSERVICE is undefined.. DSL: , Path: models.test

Просто ради здравого смысла, если я изменю test чтобы testService получает ссылку после того, как объект построен, все работает нормально. Проблема, кажется, изолирована от методов конструктора.

Как я могу убедиться, что на мои зависимости можно ссылаться в моих методах конструктора объекта? Спасибо за твою помощь!

1 ответ

Решение

В связи с порядком строительства, вы не можете использовать свойства или инъекции сеттера в init() метод. Вместо этого вы можете получить к ним доступ в onDIComplete() метод. Я понял, что в документах на WireBox есть только мимолетная ссылка на это, поэтому я добавил этот отрывок:

https://wirebox.ortusbooks.com/usage/injection-dsl/id-model-empty-namespace

Строительство ХФУ происходит в таком порядке.

  1. Компонент создается с createObject()
  2. CF автоматически запускает псевдо-конструктор (любой код вне объявления метода)
  3. init() метод вызывается (если он существует), передавая аргументы любого конструктора
  4. Свойство (mixin) и установка впрыска происходит
  5. onDIComplete() метод вызывается (если он существует)

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

component {

     property name="testService" inject="testService";

     /**
     *  Constructor
     */
     function init() {
         return this;
     }

     /**
     *  Called after property and setter injections are processed
     */
     function onDIComplete() {
         // do something in the test service
         testService.doSomething();
     }

 }

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

https://wirebox.ortusbooks.com/usage/wirebox-injector/injection-idioms

Другие вопросы по тегам