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');
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? –
Hallo Tim, ich benutze es nur um einen var_dump oder print_r einer Variablen zu bekommen. Nur zum Debuggen, wirklich. –
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