SlideShare a Scribd company logo
Dependency Injection (Внедрение Зависимостей) ZF, Zend_Application, DI Container, Symfony DI 27 марта 2010 г. Санкт-Петербург
Кирилл Чебунин Ведущий  PHP  разработчик  Equelli, ltd. Около 4 лет опыта  PHP Более 2х лет использования  ZendFramework О Докладчике
Выбор классов Адаптеры Плагины/Хелперы Интерфейсы и Реализация
Хранилище  
$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);      } }
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);      } }    
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);      } }
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 {      //[.....] } //[.....] //[.....] //[.....]
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;      } }
Конфигурация вместо кода < 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 >
Dependency Injection —    A specific form of Inversion of Control (IOC) Взято из ®Wikipedia, the free encyclopedia Внедрение зависимости —         Специфическая форма «обращения контроля»
Inversion Of Control (IOC)
PHP DI Containers Symfony Dependency Injection Yadif_Container Seasar DI Container (S2Container) Phemto Xyster_Container TYPO3  ...........
Symfony DI Container Поддержка  XML, YAML, PHP  и  INI  конфигураций Ленивая загрузка Constructor and Method Injection Shared/NotShared  ресурсы Конфигураторы Алиасы
Замена контейнера 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();
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 >
 
//[..................]  /**    * 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                );            }         }      } }
Инъекция через аннотации 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);      } }
Проблемы, советы, размышления Транзакции, сквозная функциональность
Транзакции Транзакции недоступны в сервисном слое в нашей реализации Транзакции это уровень сервисов. Может быть несколько источников данных.
Общий интерфейс транзакций 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();   }
Использование нескольких менеджеров транзакций 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();          }      }        //[.....]   }
Сквозная функциональность
 
Аспектно-ориентированное программирование (АОП)
Динамические прокси 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__          ));      } }
Добавим Аннотаций 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(); }
Хорошая архитектура  —                  Простота конфигурации < 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 >

More Related Content

PPT
Symfony2 Service Container: Inject me, my friend
PDF
Rich Model And Layered Architecture in SF2 Application
PPTX
New in php 7
PPTX
Speed up your developments with Symfony2
PDF
Diving into HHVM Extensions (PHPNW Conference 2015)
PPTX
Zephir - A Wind of Change for writing PHP extensions
PDF
Dependency Injection in PHP
PDF
PHPSpec - the only Design Tool you need - 4Developers
Symfony2 Service Container: Inject me, my friend
Rich Model And Layered Architecture in SF2 Application
New in php 7
Speed up your developments with Symfony2
Diving into HHVM Extensions (PHPNW Conference 2015)
Zephir - A Wind of Change for writing PHP extensions
Dependency Injection in PHP
PHPSpec - the only Design Tool you need - 4Developers

What's hot (20)

PDF
Forget about Index.php and build you applications around HTTP - PHPers Cracow
PDF
The IoC Hydra
PDF
Symfony without the framework
PDF
November Camp - Spec BDD with PHPSpec 2
ODP
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
PDF
Information security programming in ruby
PPTX
RESTful API 제대로 만들기
PDF
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
PDF
Apigility reloaded
PDF
Let's play a game with blackfire player
KEY
Zend Framework Study@Tokyo #2
PPTX
Zero to SOLID
PPTX
Webrtc mojo
PDF
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
PDF
Testing Backbone applications with Jasmine
PDF
Beyond Phoenix
PDF
Workshop 10: ECMAScript 6
PDF
関西PHP勉強会 php5.4つまみぐい
PDF
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
PDF
PHP Enums - PHPCon Japan 2021
Forget about Index.php and build you applications around HTTP - PHPers Cracow
The IoC Hydra
Symfony without the framework
November Camp - Spec BDD with PHPSpec 2
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Information security programming in ruby
RESTful API 제대로 만들기
The worst Ruby codes I’ve seen in my life - RubyKaigi 2015
Apigility reloaded
Let's play a game with blackfire player
Zend Framework Study@Tokyo #2
Zero to SOLID
Webrtc mojo
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Testing Backbone applications with Jasmine
Beyond Phoenix
Workshop 10: ECMAScript 6
関西PHP勉強会 php5.4つまみぐい
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
PHP Enums - PHPCon Japan 2021
Ad

Viewers also liked (15)

PDF
Чуть сложнее чем Singleton: аннотации, IOC, АОП
PPTX
SPEAK
PPT
職場見習 1022成果發表-簡單食補—阿翔的故事
PPT
EDAD MODERNA 3
PDF
Halloween
PPT
職場見習 1022成果發表-月台咖啡小館—平溪鄉的十分
PPTX
Limiting the Offshore EPC Contractor's Risks and Liabiltities, Busan korea 19...
PPT
Plantracer sl 3
DOCX
Masinile romanesti automate de spalat rufe automatic
PPTX
Limiting the Offshore EPC Contractor's Risks and Liabilities
PPT
Dependency management in PHP & ZendFramework 2
PPTX
Limiting the Offshore EPC Contractor's Risks and Liabiltities, Busan korea 19...
PPT
PPT
Powert point
PPTX
Work design & measurement
Чуть сложнее чем Singleton: аннотации, IOC, АОП
SPEAK
職場見習 1022成果發表-簡單食補—阿翔的故事
EDAD MODERNA 3
Halloween
職場見習 1022成果發表-月台咖啡小館—平溪鄉的十分
Limiting the Offshore EPC Contractor's Risks and Liabiltities, Busan korea 19...
Plantracer sl 3
Masinile romanesti automate de spalat rufe automatic
Limiting the Offshore EPC Contractor's Risks and Liabilities
Dependency management in PHP & ZendFramework 2
Limiting the Offshore EPC Contractor's Risks and Liabiltities, Busan korea 19...
Powert point
Work design & measurement
Ad

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

PPT
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
PPTX
Adding Dependency Injection to Legacy Applications
ODP
Dependency Injection, Zend Framework and Symfony Container
PDF
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
PPT
Zend framework 03 - singleton factory data mapper caching logging
PDF
Zend Framework 2 - Basic Components
PDF
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
Adding Dependency Injection to Legacy Applications
Dependency Injection, Zend Framework and Symfony Container
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Zend framework 03 - singleton factory data mapper caching logging
Zend Framework 2 - Basic Components
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)

Recently uploaded (20)

PDF
Dating And Courtship Quotes Handbook By Walter Tynash.pdf
PDF
The Zeigarnik Effect by Meenakshi Khakat.pdf
PPTX
Chapter-7-The-Spiritual-Self-.pptx-First
PPT
Spirituality_Typical_Student FOR rdneb religion.ppt
PPTX
How to Manage Emotional Triggers for Personal Growth?
PPTX
Sharks presentation & Self Representaion.pptx
PPTX
Pradeep Kumar Roll no.30 Paper I.pptx....
PPT
lecture1.pptsabdjhbdhsavfsafkaskjfbksabfksabfkabfb
PPTX
Learn numerology content and join tarot reading
PPTX
PERDEV-LESSON-3 DEVELOPMENTMENTAL STAGES.pptx
PPTX
Personal Development - By Knowing Oneself?
PPTX
cấu trúc sử dụng mẫu Cause - Effects.pptx
PPTX
SELF ASSESSMENT -SNAPSHOT.pptx an index of yourself by Dr NIKITA SHARMA
PDF
My 'novel' Account of Human Possibility pdf.pdf
PDF
The Power of Pausing Before You React by Meenakshi Khakat
PPTX
this was uploaded by gurvindertimepass.pptx
PPTX
Module-1-Nature-and-Process-of-Communication.pptx
PPTX
Presentation on interview preparation.pt
PDF
The Spotlight Effect No One Is Thinking About You as Much as You Think - by M...
PDF
Elle Lalli on The Role of Emotional Intelligence in Entrepreneurship
Dating And Courtship Quotes Handbook By Walter Tynash.pdf
The Zeigarnik Effect by Meenakshi Khakat.pdf
Chapter-7-The-Spiritual-Self-.pptx-First
Spirituality_Typical_Student FOR rdneb religion.ppt
How to Manage Emotional Triggers for Personal Growth?
Sharks presentation & Self Representaion.pptx
Pradeep Kumar Roll no.30 Paper I.pptx....
lecture1.pptsabdjhbdhsavfsafkaskjfbksabfksabfkabfb
Learn numerology content and join tarot reading
PERDEV-LESSON-3 DEVELOPMENTMENTAL STAGES.pptx
Personal Development - By Knowing Oneself?
cấu trúc sử dụng mẫu Cause - Effects.pptx
SELF ASSESSMENT -SNAPSHOT.pptx an index of yourself by Dr NIKITA SHARMA
My 'novel' Account of Human Possibility pdf.pdf
The Power of Pausing Before You React by Meenakshi Khakat
this was uploaded by gurvindertimepass.pptx
Module-1-Nature-and-Process-of-Communication.pptx
Presentation on interview preparation.pt
The Spotlight Effect No One Is Thinking About You as Much as You Think - by M...
Elle Lalli on The Role of Emotional Intelligence in Entrepreneurship

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

  • 1. Dependency Injection (Внедрение Зависимостей) ZF, Zend_Application, DI Container, Symfony DI 27 марта 2010 г. Санкт-Петербург
  • 2. Кирилл Чебунин Ведущий PHP разработчик Equelli, ltd. Около 4 лет опыта PHP Более 2х лет использования ZendFramework О Докладчике
  • 3. Выбор классов Адаптеры Плагины/Хелперы Интерфейсы и Реализация
  • 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 = &quot;Stream&quot; resources.log.file.writerParams.stream = &quot;/var/log/myapp.log&quot; 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 Внедрение зависимости —       Специфическая форма «обращения контроля»
  • 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();         }     }       //[.....]   }
  • 25.  
  • 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 >

Editor's Notes

  • #12: * Instead of your program running the system, the system runs your program * Controller