Skip to content

Commit

Permalink
Optimizing service consumption with Service Subscription. Moved a ser…
Browse files Browse the repository at this point in the history
…vice with several optional dependencies to a separate package.
  • Loading branch information
grikdotnet committed Jan 5, 2021
1 parent a26820a commit 61a1c04
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 36 deletions.
32 changes: 29 additions & 3 deletions packages/acme-image/src/ImageService.php
Expand Up @@ -3,15 +3,41 @@

namespace Acme\Image;

use Acme\Storage\{Cloudinary,File,S3};
use Psr\Container\ContainerInterface;
use Symfony\Contracts\Service\ServiceSubscriberInterface;

/**
* Empty ImageService
* Class ImageService provides an API for the application.
* It is a bridge registered as a service assisting decoupling the module
* to change it independently from the service API.
*
* @package Acme\Image
* @api
*/
final class ImageService
final class ImageService implements ServiceSubscriberInterface
{
public function __construct()
public function __construct(private ContainerInterface $locator)
{
}

/**
* @see https://symfony.com/doc/current/service_container/service_subscribers_locators.html
* @return string[]
*/
public static function getSubscribedServices(): array
{
return [ File::class, S3::class, Cloudinary::class ];
}

public function store($type,$file)
{
//Select a storage solutions based on purpose
$storage = match ($type) {
'avatar' => $this->locator->get(File::class),
'post' => $this->locator->get(S3::class),
default => $this->locator->get(Cloudinary::class),
};
$storage->store($file);
}
}
17 changes: 16 additions & 1 deletion public/index.php
@@ -1,10 +1,25 @@
<?php

include '../vendor/autoload.php';
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;

// Usually an application kernel creates
// an IoC-container, routing, middleware, controllers,
// but for the demo I'll create a container and a controller.

$containerBuilder = new ContainerBuilder();
$loader = new PhpFileLoader($containerBuilder, new FileLocator('..'));
$loader->load('services.php');
$containerBuilder->compile();
// in a real project there will be some cacheing of the compiled container

try {
$controller = new \Acme\ImageController;
/**
* @var \Acme\ImageController $controller
*/
$controller = $containerBuilder->get(\Acme\ImageController::class);
} catch (Exception $e) {
echo $e->getMessage(),"\n",$e->getTraceAsString();
exit;
Expand Down
9 changes: 9 additions & 0 deletions services.php
Expand Up @@ -2,9 +2,18 @@

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Acme\Image\ImageService;
use Acme\ImageController;

return function(ContainerConfigurator $configurator) {
/**
* @see https://symfony.com/doc/current/service_container/autowiring.html
*/
$services = $configurator->services()->defaults()->autowire()->public();

$services->set(ImageService::class)->tag('container.service_subscriber');

$services->set(ImageController::class);

$services->load('Acme\\Storage\\', './src/Storage/*');
};
7 changes: 3 additions & 4 deletions src/ImageController.php
Expand Up @@ -2,13 +2,12 @@

namespace Acme;

use Acme\Image\ImageService;

class ImageController
{
private ImageLib $imageLib;

public function __construct()
public function __construct(private ImageService $imageLib)
{
$this->imageLib = new ImageLib();
}

public function upload()
Expand Down
27 changes: 0 additions & 27 deletions src/ImageLib.php

This file was deleted.

4 changes: 3 additions & 1 deletion src/Storage/File.php
Expand Up @@ -5,5 +5,7 @@
class File
{
public function store()
{}
{
echo 'file stored';
}
}

0 comments on commit 61a1c04

Please sign in to comment.