diff --git a/ServiceLocator/DatabaseService.php b/ServiceLocator/DatabaseService.php new file mode 100644 index 0000000..1ce34f9 --- /dev/null +++ b/ServiceLocator/DatabaseService.php @@ -0,0 +1,8 @@ +services = array(); + $this->instantiated = array(); + $this->shared = array(); + } + + /** + * Registers a service with specific interface. + * + * @param string $interface + * @param string|object $service + * @param bool $share + */ + public function add($interface, $service, $share = true) + { + /** + * When you add a service, you should register it + * with its interface or with a string that you can use + * in the future even if you will change the service implementation. + */ + + if(is_object($service) && $share) + $this->instantiated[$interface] = $service; + + $this->services[$interface] = (is_object($service) ? get_class($service) : $service); + $this->shared[$interface] = $share; + } + + /** + * Checks if a service is registered. + * + * @param string $interface + * + * @return bool + */ + public function has($interface) + { + return (isset($this->services[$interface]) || isset($this->instantiated[$interface])); + } + + /** + * Gets the service registered for the interface. + * + * @param string $interface + * + * @return mixed + */ + public function get($interface) + { + // Retrieves the instance if it exists and it is shared + if(isset($this->instantiated[$interface]) && $this->shared[$interface]) + return $this->instantiated[$interface]; + + // otherwise gets the service registered. + $service = $this->services[$interface]; + + // You should check if the service class exists and + // the class is instantiable. + + // This example is a simple implementation, but + // when you create a service, you can decide + // if $service is a factory or a class. + // By registering a factory you can create your services + // using the DependencyInjection pattern. + + // ... + + // Creates the service object + $object = new $service(); + + // and saves it if the service must be shared. + if($this->shared[$interface]) + $this->instantiated[$interface] = $object; + + return $object; + } +} \ No newline at end of file diff --git a/ServiceLocator/ServiceLocatorInterface.php b/ServiceLocator/ServiceLocatorInterface.php new file mode 100644 index 0000000..ffd4006 --- /dev/null +++ b/ServiceLocator/ServiceLocatorInterface.php @@ -0,0 +1,24 @@ +serviceLocator = new ServiceLocator(); + + $this->logService = new LogService(); + $this->databaseService = new DatabaseService(); + } + + public function testHasServices() + { + $this->serviceLocator->add('DesignPatterns\ServiceLocator\LogServiceInterface', $this->logService); + $this->serviceLocator->add('DesignPatterns\ServiceLocator\DatabaseServiceInterface', $this->databaseService); + + $this->assertTrue($this->serviceLocator->has('DesignPatterns\ServiceLocator\LogServiceInterface')); + $this->assertTrue($this->serviceLocator->has('DesignPatterns\ServiceLocator\DatabaseServiceInterface')); + + $this->assertFalse($this->serviceLocator->has('DesignPatterns\ServiceLocator\FakeServiceInterface')); + } + + public function testServicesWithObject() + { + $this->serviceLocator->add('DesignPatterns\ServiceLocator\LogServiceInterface', $this->logService); + $this->serviceLocator->add('DesignPatterns\ServiceLocator\DatabaseServiceInterface', $this->databaseService); + + $this->assertSame($this->logService, $this->serviceLocator->get('DesignPatterns\ServiceLocator\LogServiceInterface')); + $this->assertSame($this->databaseService, $this->serviceLocator->get('DesignPatterns\ServiceLocator\DatabaseServiceInterface')); + } + + public function testServicesWithClass() + { + $this->serviceLocator->add('DesignPatterns\ServiceLocator\LogServiceInterface', get_class($this->logService)); + $this->serviceLocator->add('DesignPatterns\ServiceLocator\DatabaseServiceInterface', get_class($this->databaseService)); + + $this->assertNotSame($this->logService, $this->serviceLocator->get('DesignPatterns\ServiceLocator\LogServiceInterface')); + $this->assertInstanceOf('DesignPatterns\ServiceLocator\LogServiceInterface', $this->serviceLocator->get('DesignPatterns\ServiceLocator\LogServiceInterface')); + + $this->assertNotSame($this->databaseService, $this->serviceLocator->get('DesignPatterns\ServiceLocator\DatabaseServiceInterface')); + $this->assertInstanceOf('DesignPatterns\ServiceLocator\DatabaseServiceInterface', $this->serviceLocator->get('DesignPatterns\ServiceLocator\DatabaseServiceInterface')); + } + + public function testServicesNotShared() + { + $this->serviceLocator->add('DesignPatterns\ServiceLocator\LogServiceInterface', $this->logService, false); + $this->serviceLocator->add('DesignPatterns\ServiceLocator\DatabaseServiceInterface', $this->databaseService, false); + + $this->assertNotSame($this->logService, $this->serviceLocator->get('DesignPatterns\ServiceLocator\LogServiceInterface')); + $this->assertInstanceOf('DesignPatterns\ServiceLocator\LogServiceInterface', $this->serviceLocator->get('DesignPatterns\ServiceLocator\LogServiceInterface')); + + $this->assertNotSame($this->databaseService, $this->serviceLocator->get('DesignPatterns\ServiceLocator\DatabaseServiceInterface')); + $this->assertInstanceOf('DesignPatterns\ServiceLocator\DatabaseServiceInterface', $this->serviceLocator->get('DesignPatterns\ServiceLocator\DatabaseServiceInterface')); + } +} + \ No newline at end of file