2013-11-28 5 views
5

Ich habe gerade angefangen, ZF2 zu benutzen und genieße es wirklich.Alternativen zu Zend Registry für ZF2

Eine Sache, die mich etwas verwirrt, ist die Abwesenheit einer Registrierungskomponente. Ich weiß, dass der Service Manager die Registry in den meisten Fällen überflüssig macht. Ich verlasse mich stark darauf und es ist großartig.

Aber von Zeit zu Zeit brauche ich Zugriff auf ein 'globales' Objekt, und ich habe keinen Zugriff auf den Service Manager. Zum Beispiel benötige ich in meinem Domain \ User-Objekt Zugriff auf ein Zend \ Log.

Ich möchte den Service Manager nicht in meinen Domain-Objekten verfügbar machen, da sie schön und makellos sind und durch solche Überlegungen unverfälscht sind. Ich könnte eine Log-Instanz bei Bedarf "neu" erstellen, aber ich tue es so oft, dass ich lieber eine vorkonfigurierte Instanz zur Hand hätte. Ich könnte es in ein Singleton wickeln, aber das scheint ein Rückschritt zu sein. Ich könnte meine eigene Mini-Registry erstellen, aber wenn das eine gute Idee wäre, hätte ich sicher, dass die Zend-Leute eine solche Komponente an Ort und Stelle haben würden.

Also, welche anderen Optionen gibt es?

EDIT:

So konnte ich Zend DI vielleicht? Ich sehe diese Frage deckt es teilweise, Configuring class alias for using with Zend\Di\Di

+4

Der "richtige" Weg wäre, das Log-Objekt als Abhängigkeit in Ihr Domain \ User-Objekt zu übergeben. Die Protokollierung ist normalerweise nicht in Domänenmodellen möglich - können Sie etwas mehr darüber erklären, warum Sie dies benötigen? –

+0

Hallo Tim, ich benutze es nur um einen var_dump oder print_r einer Variablen zu bekommen. Nur zum Debuggen, wirklich. –

+0

Ihre Bearbeitung hört sich gut an - Zend \ Di \ Di scheint eine gute Alternative zu sein, um die Abhängigkeit bei der Objektkonstruktion zu erfassen. Aber, wie Sie erwähnt haben, sollte dies nur getan werden, wenn es überhaupt keine echte Abhängigkeit (wie Protokollierung) ist. – P0rnflake

Antwort

3

Sie sind genau auf das Problem der Abhängigkeitsinjektion. Ich habe vorher über dieses Thema gebloggt, wie zu refactor towards dependency injection und was zu tun ist, wenn Sie soft dependencies wie ein Logger haben.

Die Idee ist, injizieren Sie den vorkonfigurierten Logger. Wenn das Objekt Domain \ User erstellt wird, wird der Logger injiziert. Dies macht das Domain \ User-Objekt nur abhängig vom Logger, ohne das Wissen, wie man den Logger erstellt. Es ist sogar noch besser, wenn Sie sich auf eine Logger-Schnittstelle verlassen, so dass Sie zu jeder gewünschten Logger-Implementierung wechseln können.

Beispiel

Als Beispiel nehme ich Sie Zend \ Log verwenden. Sie haben einen Logger wie Zend\Log\Logger mit verschiedenen angeschlossenen Writern. Der Logger implementiert Zend\Log\LoggerInterface.

Ihre Domain \ User Klasse:

namespace Domain; 

Zend\Log\LoggerInterface; 

class User 
{ 
    protected $logger; 

    public function __construct(LoggerInterface $logger) 
    { 
     $this->logger = $logger; 
    } 

    public function doSomething() 
    { 
     $this->logger->info('Do Something'); 

     // 
    } 
} 

Für Zend Framework, sollten Sie mit Fabriken arbeiten, um diesen Loggers in Ihre Objekte zu injizieren. Am besten definieren Sie den Logger zuerst als Service, da Sie den Logger auch für andere Objekte verwenden können.

Hinweis Ich verwende hier den Service Manager und nicht Zend \ Di. Zend \ Di ist veraltet und wird durch den schnelleren und flexibleren Zend \ ServiceManager ersetzt. Beide können eine Abhängigkeitsinjektion erreichen.

Die Fabrik für Sie Logger:

namespace MyModule\Factory; 

use Zend\ServiceManager\FactoryInterface; 
use Zend\ServiceManager\ServiceLocatorInterface; 

use Zend\Log\Logger; 

class LoggerFactory implements FactoryInterface 
{ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $logger = new Logger; 
     // do more with $logger here 

     return $logger; 
    } 
} 

Dann dieses Werk registrieren Sie den Dienst "Logger" für Sie zu erstellen. In Ihrem module.config.php:

'service_manager' => array(
    'factories' => array(
     'logger' => 'MyModule\Factory\LoggerFactory', 
    ), 
), 

Jetzt ist logger in Ihrem Service Krippe zur Verfügung. Machen Sie dasselbe für Ihr Domänenmodell.Erstellen Sie eine Fabrik zuerst:

namespace MyModule\Factory; 

use Zend\ServiceManager\FactoryInterface; 
use Zend\ServiceManager\ServiceLocatorInterface; 

use Domain\User; 

class UserFactory implements FactoryInterface 
{ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $logger = $serviceLocator->get('logger'); 

     $user = new User($logger); 
     return $user; 
    } 
} 

Dann diese ein Register zu:

'service_manager' => array(
    'factories' => array(
     'logger' => 'MyModule\Factory\LoggerFactory', 
     'Domain\User' => 'MyModule\Factory\UserFactory', 
    ), 
), 

Wenn Sie den Zugriff auf den Service Locator haben, können Sie die Domain \ User erhalten und der Logger automatisch injiziert:

$user = $sl->get('Domain\User');