Your SlideShare is downloading. ×
  • Like
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency Injection)
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency Injection)

  • 688 views
Published

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
688
On SlideShare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
1
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • * Instead of your program running the system, the system runs your program * Controller

Transcript

  • 1. Dependency Injection (Внедрение Зависимостей) ZF, Zend_Application, DI Container, Symfony DI 27 марта 2010 г. Санкт-Петербург
  • 2.
    • Кирилл Чебунин
    • Ведущий PHP разработчик Equelli, ltd.
    • Около 4 лет опыта PHP
    • Более 2х лет использования ZendFramework
    О Докладчике
  • 3. Выбор классов
      • Адаптеры
      • Плагины/Хелперы
      • Интерфейсы и Реализация
  • 4. Хранилище
    •  
  • 5. $GLOBALS
    • $logger = new Zend_Log();
    • $writer = new Zend_Log_Writer_Stream( '/var/log/myapp.log' );
    • $logger ->addWriter( $writer );
    • $GLOBALS [ 'log' ] = $logger ;
    • class UserController extends Zend_Controller_Action
    • {
    •     public function indexAction()
    •     {
    •         /* @var $log Zend_Log */
    •         $log = $GLOBALS [ 'log' ];
    •         $log ->log( 'Index Action' , Zend_Log::INFO);
    •     }
    •     public function secondAction()
    •     {
    •         /* @var $log Zend_Log */
    •          $log = $GLOBALS [ 'log' ];
    •          $log ->log( 'Second Action' , Zend_Log::INFO);
    •     }
    • }
  • 6. Zend_Registry
    • $logger = new Zend_Log();
    • $writer = new Zend_Log_Writer_Stream( '/var/log/myapp.log' );
    • $logger ->addWriter( $writer );
    • Zend_Registry::set( 'log' , $logger );
    • class UserController extends Zend_Controller_Action
    • {
    •     public function indexAction()
    •      {
    •         /* @var $log Zend_Log */
    •         $log = Zend_Registry::get( 'log' );
    •         $log ->log( 'Index Action' , Zend_Log::INFO);
    •      }
    •     public function secondAction()
    •     {
    •         /* @var $log Zend_Log */
    •         $log = Zend_Registry::get( 'log' );
    •         $log ->log( 'Second Action' , Zend_Log::INFO);
    •     }
    • }
    •    
  • 7. Zend_Application
    • [production]
    • resources.log.file.writerName = "Stream" resources.log.file.writerParams.stream = "/var/log/myapp.log"
    • class UserController extends Zend_Controller_Action
    • {
    •     public function indexAction()
    •     {
    •         /* @var $log Zend_Log */
    •         $log = $this ->getInvokeArg( 'bootstrap' )->getResource( 'log' );
    •         $log ->log( 'Index Action' , Zend_Log::INFO);
    •     }
    •     public function secondAction()
    •     {
    •         /* @var $log Zend_Log */
    •         $log = $this ->getInvokeArg( 'bootstrap' )->getResource( 'log' );
    •         $log ->log( 'Second Action' , Zend_Log::INFO);
    •     }
    • }
  • 8. Zend_Application              & Dependency Injection
    • class My_Application_Resource_Service_UserService
    •      extends Zend_Application_Resource_ResourceAbstract
    • {
    •      //[.....]
    • }
    • class My_Application_Resource_Service_PostService
    •      extends Zend_Application_Resource_ResourceAbstract
    • {
    •      //[.....]
    • }
    • class My_Application_Resource_Service_ArticleService
    •      extends Zend_Application_Resource_ResourceAbstract
    • {
    •      //[.....]
    • }
    • class My_Application_Resource_Service_RoleService
    •      extends Zend_Application_Resource_ResourceAbstract
    • {
    •      //[.....]
    • }
    • //[.....]
    • //[.....]
    • //[.....]
  • 9. Zend_Application              & Dependency Injection
    • class Zend_Application_Resource_Log
    •     extends Zend_Application_Resource_ResourceAbstract
    • {
    •     //[.....]
    •     /**
    •      * Defined by Zend_Application_Resource_Resource
    •      *
    •      * @return Zend_Log
    •      */
    •     public function init()
    •     {
    •         return $this ->getLog();
    •     }
    •     //[.....]
    •  
    •     public function getLog()
    •     {
    •         if (null === $this ->_log) {
    •             $options = $this ->getOptions();
    •             $log = Zend_Log::factory( $options );
    •             $this ->setLog( $log );
    •         }
    •         return $this ->_log;
    •     }
    • }
  • 10. Конфигурация вместо кода
    • < service id = &quot;log&quot; class = &quot;Zend_Log&quot; constructor = &quot;factory&quot; >
    • < argument type = &quot;collection&quot; >
    •                  < argument key = &quot;file&quot; type = &quot;collection&quot; >
    •                          < argument key = &quot;writerName&quot; > Stream </ argument >
    •                          < argument key = &quot;writerParams&quot; type = &quot;collection&quot; >
    •                                  < argument key = &quot;stream&quot; > /var/log/myapp.log </ argument >
    •                          </ argument >
    •                  </ argument >
    •          </ argument >
    • </ service >
    • < service id = &quot;log&quot; class = &quot;Zend_Log&quot; >
    •          < call method = &quot;addWriter&quot; >
    •                  < argument type = &quot;service&quot; >
    •                          < service class = &quot;Zend_Log_Writer_Stream&quot; >
    •                                  < argument > /var/log/myapp.log </ argument >
    •                          </ service >
    •                  </ argument >
    •          </ call >
    • </ service >
  • 11.
      • Dependency Injection —
    •  
    • A specific form of Inversion of Control (IOC)
    Взято из ®Wikipedia, the free encyclopedia
      • Внедрение зависимости —
    •  
      •     Специфическая форма «обращения контроля»
  • 12. Inversion Of Control (IOC)
  • 13. PHP DI Containers
      • Symfony Dependency Injection
      • Yadif_Container
      • Seasar DI Container (S2Container)
      • Phemto
      • Xyster_Container
      • TYPO3
      • ...........
  • 14. Symfony DI Container
      • Поддержка XML, YAML, PHP и INI конфигураций
      • Ленивая загрузка
      • Constructor and Method Injection
      • Shared/NotShared ресурсы
      • Конфигураторы
      • Алиасы
  • 15. Замена контейнера
    • require_once 'Zend/Application.php' ;
    • require_once 'sfServiceContainerBuilder.php' ;
    • require_once 'sfServiceContainerLoaderFileXml.php' ;
    • //Create Container and load configuration from file
    • $container = new sfServiceContainerBuilder();
    • $loader = new sfServiceContainerLoaderFileXml($container);
    • $loader ->load(APPLICATION_PATH . '/configs/dependencies.xml' );
    • // Create application, bootstrap, and run
    • $application = new Zend_Application(
    •      APPLICATION_ENV,
    •      APPLICATION_PATH . '/configs/application.ini'
    • );
    • $application ->getBootstrap()->setContainer( $container );
    • $application ->bootstrap()
    •              ->run();
  • 16. Dependencies.xml
    • <? xml version = &quot;1.0&quot; encoding = &quot;UTF-8&quot; ?>
    • < container xmlns = &quot;http://symfony-project.org/2.0/container&quot; >
    •         < services >
    •             < service id = &quot;userMapper&quot; class = &quot;UserMapperImpl&quot; />
    •                 < service id = &quot;PostMapper&quot; class = &quot;PostMapperImpl&quot; />
    •                 < service id = &quot;CommentMapper&quot; class = &quot;CommentMapperImpl&quot; />
    •                 < service id = &quot;postService&quot; class = &quot;PostServiceImpl&quot; >
    •                         < call method = &quot;setUserMapper&quot; >
    •                                 < argument type = &quot;service&quot; id = &quot;userMapper&quot; />
    •                         </ call >
    •                         < call method = &quot;setPostMapper&quot; >
    •                                 < argument type = &quot;service&quot; id = &quot;postMapper&quot; />
    •                         </ call >
    •                         < call method = &quot;setCommentMapper&quot; >
    •                                 < argument type = &quot;service&quot; id = &quot;commentMapper&quot; />
    •                         </ call >
    •                 </ service >
    •  
    •         < service id = &quot;userService&quot; class = &quot;UserServiceImpl&quot; >
    •                         < call method = &quot;setUserMapper&quot; >
    •                                 < argument type = &quot;service&quot; id = &quot;userMapper&quot; />
    •                         </ call >
    •                 </ service >
    •         </ services >
    •  
    • </ container >
  • 17.  
  • 18. //[..................] /**   * Inject properties on Pre-Dispatch   */ public function preDispatch() {         $actionController = $this ->getActionController();         $class = new Zend_Reflection_Class( $actionController );         $properties = $class ->getProperties();         /* @var $property Zend_Reflection_Property */         foreach ( $properties as $property ) {                 if ( $property ->getDocComment()->hasTag( 'Inject' )) {                         $injectTag = $property ->getDocComment()->getTag( 'Inject' );                         $serviceName = $injectTag ->getDescription();                           if ( empty ( $serviceName )) {                                 $serviceName = $this ->_formatServiceName(                                         $property ->getName());           }             if ( isset ( $this ->_сontainer-> $serviceName )) {                                 $this ->_injectProperty(                                         $property ,                                         $this ->_container-> $serviceName               );           }        }     } }
  • 19. Инъекция через аннотации
    • class UserController extends Zend_Controller_Action
    • {
    •     /**
    •      * Logger
    •      * @var Zend_Log
    •      * @Inject
    •      */
    •     private $_log ;
    •     public function setLog( $log )
    •   {
    •         $this ->_log = $log ;
    •     }
    •     public function indexAction()
    •     {
    •         $this ->_log->log( 'Index Action' , Zend_Log::INFO);
    •     }
    •     public function secondAction()
    •     {
    •         $this ->_log->log( 'Second Action' , Zend_Log::INFO);
    •     }
    • }
  • 20. Проблемы, советы, размышления Транзакции, сквозная функциональность
  • 21. Транзакции
    • Транзакции недоступны в сервисном слое в нашей реализации
    • Транзакции это уровень сервисов.
    • Может быть несколько источников данных.
  • 22. Общий интерфейс транзакций
    • interface TransactionManager
    • {
    •     /**
    •      * Start a new transaction
    •      * @return unknown_type
    •      */
    •     public function beginTransaction();
    •  
    •     /**
    •      * Commit the current transaction
    •      * @return unknown_type
    •      */
    •     public function commit();
    •  
    •     /**
    •      * Rollback the current transcation
    •      * @return unknown_type
    •      */
    •     public function rollback();
    •  
    • }
  • 23. Использование нескольких менеджеров транзакций
    • class MultipleTransactionManager implements TransactionManager
    • {
    •     private $tms = array ();
    •  
    •     public function setTransactionManagers( array $tms )
    •     {
    •         $this ->tms = $tms ;
    •         return $this ;
    •     }
    •  
    •     public function beginTransaction()
    •     {
    •         /* @var $tm TransactionManager */
    •         foreach ( $this ->tms as $tm ) {
    •             $tm ->beginTransaction();
    •         }
    •     }
    •  
    •     //[.....]
    •  
    • }
  • 24. Сквозная функциональность
  • 25.  
  • 26. Аспектно-ориентированное программирование (АОП)
  • 27. Динамические прокси
    • class SomeClass
    • {
    •     public function someMethod() {}
    • }
    • class __GeneratedDynamicProxy__ extends SomeClass
    • {
    •     private $proxyManager ;
    •  
    •     public function someMethod()
    •     {
    •         return $this ->proxyManager->invoke( new ReflectionMethod(
    •             get_parent_class( $this ),
    •             __FUNCTION__
    •         ));
    •     }
    • }
  • 28. Добавим Аннотаций
    • public function someMethod()
    • {
    •      $this ->log(__METHOD__ . ' start' );
    •      if ( $this ->user->role != 'ROLE_ADMIN' ) {
    •          throw new SecuredException( $this ->user->role);
    •      }
    •      $tm = $this ->tm;
    •      $tm ->beginTransaction();
    •      try {
    •          doBusiness();
    •          $tm- >commit();
    •      } catch (Exception $e ) {
    •          $tm ->rollback();
    • throw $e ;
    •      }
    •      $this ->log(__METHOD__ . ' end' );
    • }
    /**   * Some business method   * @Transactional   * @Log   * @Secured ROLE_ADMIN   */ public function someMethod() {      doBusiness(); }
  • 29. Хорошая архитектура —                 Простота конфигурации
    • < service id = &quot;actionHelperStack&quot;  
    •          class = &quot;Zend_Controller_Action_HelperBroker&quot;  
    •          constructor = &quot;getStack&quot; >
    •      < call method = &quot;push&quot; >
    •          < argument type = &quot;service&quot; >
    •                  < service class = &quot;Zend_Controller_Action_Helper_ViewRenderer&quot; >
    •                  < argument type = &quot;service&quot; id = &quot;view&quot; />
    •              </ service >
    •          </ argument >
    •      </ call >
    •      < call method = &quot;push&quot; >
    •          < argument type = &quot;service&quot; >
    •                  < service class = &quot;My_Controller_Action_Helper_DI&quot; />
    • </ argument >
    •      </ call >
    • </ service >