【问题标题】:Alternatives to Zend Registry for ZF2ZF2 Zend Registry 的替代品
【发布时间】:2013-12-14 01:38:44
【问题描述】:

我刚刚开始使用 ZF2,非常喜欢它。

让我有点困惑的是没有注册表组件。我意识到服务管理器在大多数情况下会使注册表过时。我非常依赖它,而且它很棒。

但有时我发现自己需要访问“全局”对象,而我无权访问服务管理器。例如,在我的 Domain\User 对象中,我需要访问 Zend\Log。

我不想让服务管理器在我的域对象中可用,因为它们既漂亮又原始,并且不受这些因素的影响。我可以在需要时“新建”一个日志实例,但我经常这样做,我宁愿手头有一个预配置的实例。我可以将它包装在一个单例中,但这似乎是一个倒退。我可以创建自己的迷你注册表,但如果这是个好主意,我相信 Zend 的人会留下这样的组件。

那么,还有哪些其他选择?

编辑:

那么,我可以使用 Zend DI 吗?我看到这个问题部分涵盖了它,Configuring class alias for using with Zend\Di\Di

【问题讨论】:

  • “正确”的方法是将 Log 对象作为依赖项传递到您的 Domain\User 对象中。但是,日志记录不是您通常在域模型中执行的操作 - 您能否详细解释一下您为什么需要它?
  • 嗨,蒂姆,我用它只是为了获取变量的 var_dump 或 print_r。只是为了调试,真的。
  • 您的编辑听起来不错 - Zend\Di\Di 似乎是在对象构造中感染依赖的一个不错的替代方案。但是,正如您所提到的,只有在它根本不是真正的依赖项(例如日志记录)时才应该这样做。
  • 为什么不在服务管理器中注册为服务
  • 如何将“日志功能”从美丽而原始的域实体中移开?

标签: php zend-framework dependencies zend-framework2 registry


【解决方案1】:

您正在解决依赖注入的问题。我之前写过关于这个话题的博客,如何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');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    • 2023-04-01
    • 1970-01-01
    • 2012-11-10
    相关资源
    最近更新 更多