Как сделать внедренную зависимость 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 ссылались после создания объекта, все будет работать нормально. Проблема кажется изолированной для методов конструктора.

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


person Dave L    schedule 08.11.2018    source источник


Ответы (1)


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

https://wirebox.ortusbooks.com/usage/injection-dsl/id-model-empty-namespace#cfc-instantiation-order

Сборка CFC происходит в таком порядке.

  1. Компонент создается с помощью createObject()
  2. CF автоматически запускает псевдоконструктор (любой код вне объявления метода)
  3. Вызывается метод init() (если он существует), передавая любые аргументы конструктора
  4. Свойство (миксин) и установка инъекции происходят
  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

person Brad Wood    schedule 08.11.2018