您正在解决依赖注入的问题。我之前写过关于这个话题的博客,如何refactor towards dependency injection 以及如果你有soft dependencies 之类的记录器该怎么办。
这个想法是你注入预先配置的记录器。当您的 Domain\User 对象被创建时,记录器被注入。这使得 Domain\User 对象只依赖于记录器,而不知道如何创建记录器。如果您依赖 Logger 接口,那就更好了,这样您就可以切换到您想要的任何 logger 实现。
示例
作为一个例子,我假设您正在使用 Zend\Log。你有一个像Zend\Log\Logger 这样的记录器,并附有各种作者。记录器实现Zend\Log\LoggerInterface。
您的域\用户类:
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');
//
}
}
对于 Zend Framework,您应该使用工厂将此记录器注入到您的对象中。最好的方法是首先将 Logger 定义为服务,因为您也可以将 logger 重用于其他对象。
注意我在这里使用的是服务管理器而不是 Zend\Di。 Zend\Di 已过时,取而代之的是更快、更灵活的 Zend\ServiceManager。两者都可以实现依赖注入。
记录器的工厂:
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;
}
}
然后注册这个工厂为你创建服务“记录器”。在你的 module.config.php 中:
'service_manager' => array(
'factories' => array(
'logger' => 'MyModule\Factory\LoggerFactory',
),
),
现在logger 在您的服务管理器中可用。对于您的域模型,请执行相同的操作。先创建工厂:
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;
}
}
然后也注册这个:
'service_manager' => array(
'factories' => array(
'logger' => 'MyModule\Factory\LoggerFactory',
'Domain\User' => 'MyModule\Factory\UserFactory',
),
),
如果你有访问服务定位器的权限,你可以获得 Domain\User 并且自动注入记录器:
$user = $sl->get('Domain\User');