Перекрестная инициализация компонентов

Есть два компонента, которые зависят друг от друга




class Comp1 extends CApplicationComponent {


  public function init() {


    parent::init();

    

    // зависимость от Comp2

    Yii::app()->comp2;


  }


}


class Comp2 extends CApplicationComponent {


  public function init() {


    parent::init();

    

    // зависимость от Comp1

    Yii::app()->comp1;


  }


}



следующий код генерирует ошибку ‘Undefined property: CApplication::$comp1’




Yii::app()->comp1;



чтобы реализовать такую зависимость компонентов, необходимо код зависимости вынести в отдельный метод и инициализировать компоненты вручную, например:




class MyApplication extends CWebApplication {

	

	

	/**

	 * @see CWebApplication::init()

	 */

	protected function init() {

		

		parent::init();

			

                // init both components	

		$this->comp1;

		$this->comp2;

                // process operations depends from comp2

		$this->comp1->dependsFromComp2();

		

	}

}



какой подход в реализации такой задачи является правильным в Yii?

Знаете, я даже попробовал повторить приведенный вами код, но у меня ошибок не выдало :)

ComponentA.php:




class ComponentA extends CApplicationComponent

{

    public $a = 'a';

    

    public function init()

    {

        parent::init();        

        echo Yii::app()->compB->b;

    }

}



ComponentB.php:




class ComponentB extends CApplicationComponent

{

    public $b = 'b';

    

    public function init()

    {

        parent::init();        

        echo Yii::app()->compA->a;

    }

}



В конфиге секция ‘components’:




'compA'=>array(

    'class'=>'ComponentA',

),


'compB'=>array(

    'class'=>'ComponentB',

),



Ну и в некотором экшене:




Yii::app()->compB; // или compA



Извиняюсь, если не так понял вопрос :)

у меня тоже когда-то не было. думал, что изменилось что-то в новой версии фреймворка (1.1.2)

у меня этот код выдает ту же ошибку. какая у вас версия фреймворка?

Версия 1.1.2.

Посмотрел еще раз. Оказывается, ошибку то он мне не выдает, но и компонент componentA a в методе init() класса componentB он не создает :) К сожалению, метод init() вызывается в тот момент, когда в классе приложения и из массива конфигураций модуль удален, и в массив объектов он еще не помещен…

т.е. таким способом реализовать не получится

Первая мысль (конечно, не самая хорошая), которая приходит в голову - сделать setComponent() прямо в методе init():




class ComponentA extends CApplicationComponent

{

    public $a = 'a';

    

    public function init()

    {

        parent::init();

        Yii::app()->setComponent('compA', $this);

        $b = Yii::app()->getComponent('compB');

        $b->b = 'world';

    }

}






class ComponentB extends CApplicationComponent

{

    public $b = 'b';

    

    public function init()

    {

        parent::init();

        Yii::app()->setComponent('compB', $this);

        $a = Yii::app()->getComponent('compA');

        $a->a = 'hello';

    }

}






echo Yii::app()->compA->a.' '.Yii::app()->compB->b; // prints "hello world"



Это хотя бы позволит инкапсулировать взаимодействие компонентов, чтобы не выносить его в отдельное место. Спасибо :)