From 2d8a0041d0b2bdcdf2d3dd70cd4d2229879b3c55 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sun, 7 Apr 2013 23:01:12 +0200 Subject: [PATCH 1/3] Adding documentation for lazy services --- docs/languages/en/index.rst | 1 + .../zend.service-manager.lazy-services.rst | 175 ++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 docs/languages/en/modules/zend.service-manager.lazy-services.rst diff --git a/docs/languages/en/index.rst b/docs/languages/en/index.rst index 38b23fde5..d794922fc 100644 --- a/docs/languages/en/index.rst +++ b/docs/languages/en/index.rst @@ -692,6 +692,7 @@ Zend\\ServiceManager * :doc:`modules/zend.service-manager.intro` * :doc:`modules/zend.service-manager.quick-start` * :doc:`modules/zend.service-manager.delegator-factories` + * :doc:`modules/zend.service-manager.lazy-services` .. _zend.session diff --git a/docs/languages/en/modules/zend.service-manager.lazy-services.rst b/docs/languages/en/modules/zend.service-manager.lazy-services.rst new file mode 100644 index 000000000..ec78f4004 --- /dev/null +++ b/docs/languages/en/modules/zend.service-manager.lazy-services.rst @@ -0,0 +1,175 @@ +.. _zend.service-manager.lazy-services: + +Lazy Services +============= + +``Zend\ServiceManager`` can use :ref:`delegator factories ` to +generate "lazy" references to your services. + +Lazy services are `proxies`_ that get lazily instantiated, and keep a reference to the real instance of +the proxied service. + +Use cases +^^^^^^^^^ + +You may want to lazily initialize a service when it is instantiated very often, but not always used. + +A typical example is a database connection: it is a dependency to many other elements in your application, +but that doesn't mean that every request will execute queries through it. + +Additionally, instantiating a connection to the database may require some time and eat up resources. + +Proxying the database connection would allow to delay that overhead until the object is really needed. + +Setup +^^^^^ + +```Zend\ServiceManager\Proxy\LazyServiceFactory`` is a :ref:`delegator factory` capable of generating +lazy loading proxies for your services. + +The ``LazyServiceFactory`` depends on `ProxyManager`_, so be sure to install it before going through +the following steps: + +.. code-block:: sh + + php composer.phar require ocramius/proxy-manager:0.3.* + + +Practical example +^^^^^^^^^^^^^^^^^ + +To demonstrate how a lazy service works, you may use the following ``Buzzer`` example class, which +is designed to be slow at instantiation time for demonstration purposes: + +.. code-block:: php + :linenos: + + namespace MyApp; + + class Buzzer + { + public function __construct() + { + // deliberately halting the application for 5 seconds + sleep(5); + } + + public function buzz() + { + return 'Buzz!'; + } + } + +You can then proceed and configure the service manager to generate proxies instead of real services: + +.. code-block:: php + :linenos: + + $serviceManager = new \Zend\ServiceManager\ServiceManager(); + + $config = array( + 'lazy_services' => array( + // mapping services to their class names is required + // since the ServiceManager is not a declarative DIC + 'map' => array( + 'buzzer' => 'MyApp\Buzzer', + ), + ), + ); + + $serviceManager->setService('Config', $config); + $serviceManager->setInvokableClass('buzzer', 'MyApp\Buzzer'); + $serviceManager->setFactory('LazyServiceFactory', 'Zend\ServiceManager\Proxy\LazyServiceFactoryFactory'); + $serviceManager->addDelegator('buzzer', 'LazyServiceFactory'); + +This will tell the service manager to use the ``LazyServiceFactory`` delegator factory to +instantiate the ``buzzer`` service. + +As you may have noticed, the standard setup for the ``LazyServiceFactory`` requires you to define +a ``Config`` service. That's because the functionality was thought to be easily integrated into +``Zend\Mvc``. + +You can now simply retrieve the ``buzzer``: + +.. code-block:: php + :linenos: + + $buzzer = $serviceManager->get('buzzer'); + + echo $buzzer->buzz(); + +To verify that proxying occurred correctly, you can simply run following code, which should delay the 5 +seconds wait time hardcoded in ``Buzzer::__construct`` until ``Buzzer::buzz`` is invoked: + +.. code-block:: php + :linenos: + + for ($i = 0; $i < 100; $i += 1) { + $buzzer = $serviceManager->create('buzzer'); + + echo "created buzzer $i\n"; + } + + echo $buzzer->buzz(); + +The setup above can also be represented via configuration in an MVC application's context: + +.. code-block:: php + :linenos: + + return array( + 'service_manager' => array( + 'invokables' => array( + 'buzzer' => 'MyApp\Buzzer', + ), + 'delegators' => array( + 'buzzer' => array( + 'LazyServiceFactory' + ), + ), + 'factories' => array( + 'LazyServiceFactory' => 'Zend\ServiceManager\Proxy\LazyServiceFactoryFactory', + ), + ), + 'lazy_services' => array( + 'map' => array( + 'buzzer' => 'MyApp\Buzzer', + ), + ), + ); + + +Configuration +^^^^^^^^^^^^^ + +This is the config structure expected by ``Zend\ServiceManager\Proxy\LazyServiceFactoryFactory``: + + +.. code-block:: php + :linenos: + + return array( + 'lazy_services' => array( + + // map of service names and their relative class names - this + // is required since the service manager cannot know the + // class name of defined services upfront + 'map' => array( + // 'foo' => 'MyApplication\Foo', + ), + + // directory where proxy classes will be written - default to system_get_tmp_dir() + 'proxies_target_dir' => null, + + // boolean flag to indicate whether to generate proxies + // proxies are auto-generated by default + 'auto_generate_proxies' => null, + + // namespace of the generated proxies, default to "ProxyManagerGeneratedProxy" + 'proxies_namespace' => null, + ), + ); + + +.. _`proxies`: http://en.wikipedia.org/wiki/Proxy_pattern +.. _`ProxyManager`: https://github.com/Ocramius/ProxyManager \ No newline at end of file From 1310b72b0e18dce57b9215ec2c1952f5da5fd77b Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sun, 7 Apr 2013 23:04:25 +0200 Subject: [PATCH 2/3] Adding lazy services to the index --- docs/languages/en/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/languages/en/index.rst b/docs/languages/en/index.rst index d794922fc..c1cb49f83 100644 --- a/docs/languages/en/index.rst +++ b/docs/languages/en/index.rst @@ -207,6 +207,7 @@ modules/zend.service-manager.intro modules/zend.service-manager.quick-start modules/zend.service-manager.delegator-factories + modules/zend.service-manager.lazy-services modules/zend.session.config modules/zend.session.container modules/zend.session.manager From 8d40d315d3ef8821e5302d3c69c56b20ccb5195c Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Mon, 15 Apr 2013 22:12:36 +0200 Subject: [PATCH 3/3] Minor fixes to the lazy services documentation --- .../en/modules/zend.service-manager.lazy-services.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/languages/en/modules/zend.service-manager.lazy-services.rst b/docs/languages/en/modules/zend.service-manager.lazy-services.rst index ec78f4004..32098f59b 100644 --- a/docs/languages/en/modules/zend.service-manager.lazy-services.rst +++ b/docs/languages/en/modules/zend.service-manager.lazy-services.rst @@ -98,8 +98,8 @@ You can now simply retrieve the ``buzzer``: echo $buzzer->buzz(); -To verify that proxying occurred correctly, you can simply run following code, which should delay the 5 -seconds wait time hardcoded in ``Buzzer::__construct`` until ``Buzzer::buzz`` is invoked: +To verify that the proxying occurred correctly, you can simply run the following code, which should delay +the 5 seconds wait time hardcoded in ``Buzzer::__construct`` until ``Buzzer::buzz`` is invoked: .. code-block:: php :linenos: @@ -167,6 +167,9 @@ This is the config structure expected by ``Zend\ServiceManager\Proxy\LazyService // namespace of the generated proxies, default to "ProxyManagerGeneratedProxy" 'proxies_namespace' => null, + + // whether the generated proxy classes should be written to disk + 'write_proxy_files' => false, ), );