Skip to content

Commit 3740648

Browse files
BooleanTypeLeroid
authored andcommitted
Add working usage example.
1 parent b4c7361 commit 3740648

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed

service_container/factories.rst

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,5 +301,138 @@ previous examples takes the ``templating`` service as an argument:
301301
->args([service('templating')])
302302
;
303303
};
304+
305+
Usage example
306+
--------------------
307+
308+
The following example is intended to show how to create and use a factory method in Symfony framework.
309+
Suppose you want to realize the factory method pattern for services, that describe two delivery methods - DPD and SmartPost.
310+
311+
Services (subclasses) definition::
312+
313+
// src/Deliveries/DPD.php
314+
namespace App\Deliveries;
315+
316+
class DPD
317+
{
318+
public $costLabel;
319+
320+
public function cost() {
321+
return 100;
322+
}
323+
}
324+
325+
// src/Deliveries/SmartPost.php
326+
namespace App\Deliveries;
327+
328+
class SmartPost
329+
{
330+
public $costLabel;
331+
332+
public function cost() {
333+
return 200;
334+
}
335+
}
336+
337+
Factory definition::
338+
339+
// src/Factories/DeliveryFactory.php
340+
namespace App\Factories;
341+
342+
abstract class DeliveryFactory
343+
{
344+
public static function create($deliveryMethod)
345+
{
346+
$delivery = new $deliveryMethod;
347+
$delivery->costLabel = 'Delivery cost is: ';
348+
349+
return $delivery;
350+
}
351+
352+
abstract public function price();
353+
}
354+
355+
As you can see, ``DeliveryFactory`` doesn't specify the exact class of the object that will be created.
356+
357+
Next, use settings similar to those in the sections above. These settings allow you to define a factory method for subclasses without explicitly extending the abstract class (i.e., without ``class DPD extends DeliveryFactory``)!
358+
359+
.. configuration-block::
360+
361+
.. code-block:: yaml
362+
363+
# config/services.yaml
364+
services:
365+
# ...
366+
367+
App\Deliveries\DPD:
368+
factory: ['@App\Factories\DeliveryFactory', create]
369+
arguments:
370+
$deliveryMethod: 'App\Deliveries\DPD'
371+
App\Deliveries\SmartPost:
372+
factory: ['@App\Factories\DeliveryFactory', create]
373+
arguments:
374+
$deliveryMethod: 'App\Deliveries\SmartPost'
375+
376+
377+
.. code-block:: xml
378+
379+
<!-- config/services.xml -->
380+
<?xml version="1.0" encoding="UTF-8" ?>
381+
<container xmlns="http://symfony.com/schema/dic/services"
382+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
383+
xsi:schemaLocation="http://symfony.com/schema/dic/services
384+
https://symfony.com/schema/dic/services/services-1.0.xsd">
385+
386+
<services>
387+
<!-- ... -->
388+
389+
<service id="App\Deliveries\DPD">
390+
<factory service="App\Factories\DeliveryFactory" method="create"/>
391+
<argument key="$deliveryMethod">App\Deliveries\DPD</argument>
392+
</service>
393+
<service id="App\Deliveries\SmartPost">
394+
<factory service="App\Factories\DeliveryFactory" method="create"/>
395+
<argument key="$deliveryMethod">App\Deliveries\SmartPost</argument>
396+
</service>
397+
</services>
398+
</container>
399+
400+
.. code-block:: php
401+
402+
// config/services.php
403+
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
404+
405+
use App\Deliveries\DPD;
406+
use App\Deliveries\SmartPost;
407+
use App\Factories\DeliveryFactory;
408+
409+
return function(ContainerConfigurator $configurator) {
410+
$services = $configurator->services();
411+
412+
$services->set(DPD::class)
413+
->factory([ref(DeliveryFactory::class), 'create'])
414+
->arg('$deliveryMethod', 'App\Deliveries\DPD')
415+
;
416+
$services->set(SmartPost::class)
417+
->factory([ref(DeliveryFactory::class), 'create'])
418+
->arg('$deliveryMethod', 'App\Deliveries\SmartPost')
419+
;
420+
};
421+
422+
Now we can use our services as usual (via dependency injection). The only difference is that object instances are created in the factory. Let's get those services in controller::
423+
424+
/**
425+
* @Route("/get-deliveries-cost", methods={"GET"})
426+
*/
427+
public function getDeliveriesCost(DPD $dpd, SmartPost $smartPost)
428+
{
429+
// ...
430+
431+
// $dpd->costLabel is fulfilled in factory method.
432+
$dpdCost = $dpd->costLabel . $dpd->cost();
433+
$smartPostCost = $smartPost->costLabel . $smartPost->cost();
434+
435+
// ...
436+
}
304437

305438
.. _`factory design pattern`: https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)

0 commit comments

Comments
 (0)