Содержание


Definition


Definition определение, ЗФ2, Zend Framework 2, ZF2, ру, ru




Определения (Definitions) -  это места, где Zend\Di пытается понять структуру кода, который нужно связать. Это означает, что если Вы напишите однозначный, лаконичный и понятный код, то Zend\Di быстро и правильно разберет код и внедрит зависимости без дополнительных сложностей.

 


DefinitionList

 

Определения вводятся в объект Zend\Di\Di через список определений (DefinitionList

), реализованный как Zend\Di\DefinitionList (SplDoublyLinkedList). Порядок важен.  Обрабатываются в порядке FIFO.

 

Важно: Независимо от выбранной стратегии Определений, автозагрузчик всегда установлен и готов к использованию.

 


RuntimeDefinition

 

DefinitionList по умолчанию инициализируется в Zend\Di\Di, когда еще не переданы никакие другие DefinitionList. RuntimeDefinition отвечает на запросы классов используя отражение (Reflection). RuntimeDefinition используют любую доступную информацию в методах: подпись, имена параметров, типы значений параметров, значения по умолчанию параметров если есть для определения, какие параметры являются обязательными а какие нет перед вызовом метода.  Чем больше всего указано, тем меньше времени тратится Zend\Di\Definition\RuntimeDefinition на изучение структуры кода.

 

Конструктор RuntimeDefinition имеет вид:

public function __construct(IntrospectionStrategy $introspectionStrategy = null, array $explicitClasses = null)
{
    $this->introspectionStrategy = ($introspectionStrategy) ?: new IntrospectionStrategy();
    if ($explicitClasses) {
        $this->setExplicitClasses($explicitClasses);
    }
}

Объект IntrospectionStrategy  -  это объект, определяющий правила и основные принципы того, как RuntimeDefinition будет самоанализировать Ваш класс:

 

- Использовать или нет аннотации (Annotations). Аннотации являются довольно объемными и отключены по умолчанию.

 

- Имя подключаемого метода для самоанализа по умолчанию. По умолчанию используется такая маска: «/^set[A-Z]{1}\w*/ » . Это список шаблонов.

 

- Какое имя интерфейса представляет собой образец интерфейса инъекций. По умолчанию используется такая маска: «/\w*Aware\w*/ ».

 

Конструктор IntrospectionStrategy:

public function __construct(AnnotationManager $annotationManager = null)
{
    $this->annotationManager = ($annotationManager) ?: $this->createDefaultAnnotationManager();
}

Не будет лишним напомнить, что менеджер аннотаций (AnnotationManager) не требуется. Однако, если Вы хотите создать его используя свои аннотации, а так же расширить RuntimeDefinition таким образом, что б он понимал нужные аннотации, то делать это нужно тут.

 

RuntimeDefinition так же может быть использован для поиска всех классов (косвенно являющиеся по умолчанию), или для поиска конкретных предопределенных классов. Это может быть полезно, когда несколько стратегий  проверки групп классов имеют различия. Для этого используется метод «setExplictClasses()», или передача списка классов как второй аргумент в конструктор «RuntimeDefinition».

 


CompilerDefinition

 

CompilerDefinition по своей природе очень схож с RuntimeDefinition с одной лишь разницей -  он может использоваться с большим количеством информации для «компиляции» определений. Такая возможность полезна, когда нет необходимости делать вызовы отражений и сканирования аннотаций во время запроса приложения. При использовании компилятора, определения создаются и записываются на диск, а потом уже используются во время запросов, а не сканируется код каждый раз.

 

Пример: создадим определения для одной из наших библиотек:

// in "package name" format
$components = array(
    'My_MovieApp',
    'My_OtherClasses',
);
 
foreach ($components as $component) {
    $diCompiler = new Zend\Di\Definition\CompilerDefinition;
    $diCompiler->addDirectory('/path/to/classes/' . str_replace('_', '/', $component));
 
    $diCompiler->compile();
    file_put_contents(
        __DIR__ . '/../data/di/' . $component . '-definition.php',
        '<?php return ' . var_export($diCompiler->toArrayDefinition()->toArray(), true) . ';'
    );
}

Это создаст пару файлов, которые будут возвращать массив определений для нужного класса. Для использования в приложении воспользуйтесь таким кодом:

protected function setupDi(Application $app)
{
    $definitionList = new DefinitionList(array(
        new Definition\ArrayDefinition(include __DIR__ . '/path/to/data/di/My_MovieApp-definition.php'),
        new Definition\ArrayDefinition(include __DIR__ . '/path/to/data/di/My_OtherClasses-definition.php'),
        $runtime = new Definition\RuntimeDefinition(),
    ));
    $di = new Di($definitionList, null, new Configuration($this->config->di));
    $di->instanceManager()->addTypePreference('Zend\Di\LocatorInterface', $di);
    $app->setLocator($di);
}

Вышеприведенный код вы скорей всего будете использовать в файле bootstrap приложения или модуля, так как это будет самым простым способом настроить DiC для использования.

 


ClassDefinition

 

Использование ClassDefinition дает вам два преимущества. Первое – возможно Вы захотите изменить часть информации внутри RuntimeDefinition. Второе - возможно Вы захотите определить свой класс определений, а его описание структуры хранить в одном из форматов: xml, ini, php. ClassDefinition может быть задействован через Настройки (Configuration)  или непосредственно созданием и регистрированием экземпляра определения в DefinitionList.


Автор статьи: DuB