rafaeltovar / php-service-manager
Simple, light, minimum service manager and dependency injection for PHP.
Installs: 4 901
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 0
Requires
- php: >=7.0
- psr/container: ^1.0
README
Simple, light, minimum service manager and dependency injection for PHP.
Installation
Composer
Execute:
composer require rafaeltovar/php-service-manager
Features
- Dependency injection
- Service container
- Providers
- Singleton strategy
- Initialized only if service is called
- Alias
Documentation
Service container
The service container is the main service controller for manage the service queue.
// myproject.php use MyServiceAProvider; $serviceContainer = new \ServiceManager\ServiceContainer( [MyServiceAProvider::class] );
Service Providers
This is my service.
// MyServiceA.php class MyServiceA { public function test() { echo "Working."; } }
This is my service provider.
// MyServiceAProvider.php class MyServiceAProvider extends \ServiceManager\ServiceProvider { /** * This method return the service class name (mandatory) **/ public function getServiceType() : string { return MyServiceA::class; } /** * This method return the identification of the service * into Service Container (mandatory) **/ public function getServiceId(): string { return "my-service-a"; } /** * This method return the service (mandatory) **/ public function getService() { return new MyServiceA(); } }
Passing custom arguments to the provider
Sometimes We need pass some arguments to the provider for initialize the service, like the config or logger, for example. In this case we need implements \ServiceManager\ServiceProviderArgumentsInterface
.
MyCustomArguments
will have the arguments it needs.
// myproject.php use MyServiceDebugProvider, MyServiceAProvider; use MyCustomArguments; //... $serviceContainer = new \ServiceManager\ServiceContainer( [ MyServiceAProvider::class, MyServiceDebugProvider::class ], [], new MyCustomArguments($myLogger) );
// MyCustomArguments.php class MyCustomArguments implements \ServiceManager\ServiceProviderArgumentsInterface { protected $logger; public function __construct(\Psr\Log\LoggerInterface $logger) { $this->logger = $logger; } public function getLogger() : \Psr\Log\LoggerInterface { return $this->logger; } }
My example service with argument:
// MyServiceDebug.php class MyServiceDebug { protected $logger; public function __construct(\Psr\Log\LoggerInterface $logger) { $this->logger = $logger; } public function write(string $text) { $this->logger->debug($text); } }
My example service provider:
// MyServiceDebugProvider.php class MyServiceDebugProvider extends \ServiceManager\ServiceProvider { public function getServiceType() : string { return MyServiceDebug::class; } public function getServiceId(): string { return "debug"; } public function getService() { $logger = $this->getProviderArguments()->getLogger(); return new MyServiceDebug($logger); } }
Getting a service
$serviceContainer->get("my-service-a")->test();
// result:
Working.
Dependency injection
// MyController.php class MyController { protected $a; public function __construct(MyServiceA $a) { $this->a = $a; } public function test() { $this->a->test(); } }
use MyController; //... $myCtrl = $serviceContainer->build(MyController::class); $myCtrl->test();
// result:
Working.
Custom builders
Sometime our controller need other controller or data, not a service. In those cases we can create a custom constructor implements ControllerBuilderCreateInterface
.
// MyController.php use ServiceManager\ServiceContainer, ServiceManager\ControllerBuilderCreateInterface; class MyController implements ControllerBuilderCreateInterface { protected $public; public function __construct(string $publicFolder) { $this->public = $publicFolder; } public static function create(ServiceContainer $services) { return new MyController( $services->get('config')->get("PUBLIC_FOLDER") ); } }
Now we can build our controller. The service container will call to create
method if implements ControllerBuilderCreateInterface
.
use MyController; //... $myCtrl = $serviceContainer->build(MyController::class);
Alias
Other times we need to work with interfaces, we can use aliases to obtain the services that implement these interfaces.
// myproject.php use MyServiceDebugProvider, MyServiceAProvider; use MyCustomArguments; //... $serviceContainer = new \ServiceManager\ServiceContainer( [ MyLoggerProvider::class, ], [ // aliases // interface => service id \Psr\Log\LoggerInterface::class => "logger" ] );
// MyServiceDebugProvider.php use Monolog\Logger; use Monolog\Handler\StreamHandler; class MyLoggerProvider extends \ServiceManager\ServiceProvider { public function getServiceType() : string { return Logger::class; } public function getServiceId(): string { return "logger"; } public function getService() { $log = new Logger('name'); $log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING)); return $log; } }
Now we can build our controller with interface dependency.
// MyController.php class MyController { protected $logger; public function __construct(\Psr\Log\LoggerInterface $logger) { $this->logger = $logger; // this logger will be \Monolog\Logger } // ... }
use MyController; //... $myCtrl = $serviceContainer->build(MyController::class);