Содержание


InstanceManager


InstanceManager, менеджер экземпляра, ЗФ2, Zend Framework 2, ZF2, ру, ru




InstanceManage ответственный за любую динамическую информацию, связанную с Zend\Di\Di DiC. Это означает, что информация проходящая через InstanceManage актуальна не только для приложения, но и для среды, в которой оно выполняется.

 



Параметры

 

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

 

Используем уже знакомый пример для более детального пояснения:

namespace MyLibrary
{
    class DbAdapter
    {
        protected $username = null;
        protected $password = null;
        public function __construct($username, $password)
        {
            $this->username = $username;
            $this->password = $password;
        }
    }
}
 
namespace MyMovieApp
{
    class MovieFinder
    {
        protected $dbAdapter = null;
        public function __construct(\MyLibrary\DbAdapter $dbAdapter)
        {
            $this->dbAdapter = $dbAdapter;
        }
    }
 
    class MovieLister
    {
        protected $movieFinder = null;
        public function __construct(MovieFinder $movieFinder)
        {
            $this->movieFinder = $movieFinder;
        }
    }
}

Класс «DbAdapter» располагает двумя параметрами: «username» и «password». В «MovieFinder» всего один параметр: «dbAdapter», «MovieLister» так же имеет всего один параметр: «movieFinder». Любой из ниж может быть использован для инъекции зависимости или скалярного значении в процессе создания экземпляра настроек или во время вызова.

 

Параметр «dbAdapter» и «movieFinder» имеют явное привидение типов, и поэтому DiC может их разобрать и инъекцировать сам. Однако параметры «username» и «password» не имеют явного привидения типов и скорее всего скалярны. DiC ничего этого не знает и вынужден обращаться к InstanceManager. Такой вызов метода приведет к исключению: «$di->get(‘MyMovieApp\MovieLister’)».

 

Как правильно использовать параметры:

// setting instance configuration into the instance manager
$di->instanceManager()->setParameters('MyLibrary\DbAdapter', array(
    'username' => 'myusername',
    'password' => 'mypassword'
));
 
// forcing a particular dependency to be used by the instance manager
$di->instanceManager()->setParameters('MyMovieApp\MovieFinder', array(
    'dbAdapter' => new MyLibrary\DbAdaper('myusername', 'mypassword')
));
 
// passing instance parameters at call time
$movieLister = $di->get('MyMovieApp\MovieLister', array(
    'username' => $config->username,
    'password' => $config->password
));
 
// passing a specific instance at call time
$movieLister = $di->get('MyMovieApp\MovieLister', array(
    'dbAdapter' => new MyLibrary\DbAdaper('myusername', 'mypassword')
));


Предпочтения (Preferences)



 

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

namespace MyMovieApp
{
    interface MovieFinderInterface
    {
        // methods required for this type
    }
 
    class GenericMovieFinder implements MovieFinderInterface
    {
        protected $dbAdapter = null;
        public function __construct(\MyLibrary\DbAdapter $dbAdapter)
        {
            $this->dbAdapter = $dbAdapter;
        }
    }
 
    class MovieLister
    {
        protected $movieFinder = null;
        public function __construct(MovieFinderInterface $movieFinder)
        {
            $this->movieFinder = $movieFinder;
        }
    }
}

Как Вы заметили, теперь MovieLister как минимум предполагает, что будет внедряться реализация MovieFinderInterface. Это позволяет создать несколько реализаций,основанных на этом интерфейсе, которые будут внедряться. Zend\Di не сможет сам определить  какой тип конкретного объекта использовать для заполнения зависимостью, поэтому необходимо указать «предпочтение» в InstanceManager.

 

Как передать эту информации в InstanceManager:

$di->instanceManager()->addTypePreference('MyMovieApp\MovieFinderInterface', 'MyMovieAppGenericMovieFinder');
// assuming all instance config for username, password is setup
$di->get('MyMovieApp\MovieLister');


Псевдонимы (Aliases)



 

Могут возникнуть ситуации, когда необходимо использовать псевдонимы для экземпляров. Есть две основные причины:

- Создание простых, альтернативных имен при использовании DiC, а не использовать полное имя класса.

- Необходимость получать один тип объектов в разных контекстах.

 

Это означает, что после создания псевдонима, у Вас появляется возможность прикреплять к нему экземпляр конфигурации.

 

Демонстрацию обоих подходов рассмотрим на двух отдельных «DbAdapter». Один будет только для операций чтения, а другой как для чтения так и для записи.

 

Важно: Псевдонимы так же могут иметь параметры, которые регистрируются во время создания псевдонима.

// assume the MovieLister example of code from the QuickStart
 
$im = $di->instanceManager();
 
// add alias for short naming
$im->addAlias('movielister', 'MyMovieApp\MovieLister');
 
// add aliases for specific instances
$im->addAlias('dbadapter-readonly', 'MyLibrary\DbAdapter', array(
    'username' => $config->db->readAdapter->username,
    'password' => $config->db->readAdapter->password,
));
$im->addAlias('dbadapter-readwrite', 'MyLibrary\DbAdapter', array(
    'username' => $config->db->readWriteAdapter>username,
    'password' => $config->db->readWriteAdapter>password,
));
 
// set a default type to use, pointing to an alias
$im->addTypePreference('MyLibraryDbAdapter', 'dbadapter-readonly');
 
$movieListerRead = $di->get('MyMovieApp\MovieLister');
$movieListerReadWrite = $di->get('MyMovieApp\MovieLister', array('dbAdapter' => 'dbadapter-readwrite'));

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