Kim*_*nce 5 php registry dependencies zend-framework zend-framework2
我刚开始使用ZF2,我真的非常喜欢它.
令我困惑的一件事是没有注册表组件.我意识到服务管理器在大多数情况下使注册表过时.我非常依赖它而且很棒.
但有时我发现自己需要访问"全局"对象,而我无法访问服务管理器.例如,在我的Domain\User对象中,我需要访问Zend\Log.
我不希望在我的Domain对象中提供Service Manager,因为它们非常漂亮和原始,并且没有因这些考虑因素而受到影响.我可以在需要时"新建"一个日志实例,但是我经常这么做,我宁愿预先配置一个实例.我可以把它包装成单身,但这似乎是一个倒退的步骤.我可以创建自己的迷你注册表,但如果这是一个好主意,我相信Zend家伙会留下这样的组件.
那么,还有哪些其他选择?
编辑:
那么,我可以使用Zend DI吗?我看到这个问题部分涵盖了它,使用Zend\Di\Di配置类别名
您正在解决依赖注入的问题。我之前曾在博客中讨论过这个主题,如何重构依赖注入,以及如果您有像 Logger 这样的软依赖项该怎么办。
这个想法是您注入预先配置的记录器。创建 Domain\User 对象时,将注入记录器。这使得域\用户对象仅依赖于记录器,而不知道如何创建记录器。如果您依赖 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');
//
}
}
Run Code Online (Sandbox Code Playgroud)
对于 Zend Framework,您应该与工厂合作将此记录器注入到您的对象中。最好的方法是首先将记录器定义为服务,因为您也可以将记录器重用于其他对象。
注意我在这里使用服务管理器而不是 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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后注册这个工厂来为您创建服务“logger”。在你的 module.config.php 中:
'service_manager' => array(
'factories' => array(
'logger' => 'MyModule\Factory\LoggerFactory',
),
),
Run Code Online (Sandbox Code Playgroud)
现在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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后也注册这个:
'service_manager' => array(
'factories' => array(
'logger' => 'MyModule\Factory\LoggerFactory',
'Domain\User' => 'MyModule\Factory\UserFactory',
),
),
Run Code Online (Sandbox Code Playgroud)
如果您有权访问服务定位器,则可以获得域\用户,并且记录器会自动注入:
$user = $sl->get('Domain\User');
Run Code Online (Sandbox Code Playgroud)