阅读这篇关于依赖注入(inject)的精彩文章后:http://miller.limethinking.co.uk/2011/07/07/dependency-injection-moving-from-basics-to-container/
我意识到我的小框架已经在很大程度上使用了 Denedency Injection Container。
我有一个 App 类,它管理所有服务数据库、配置、 session 的创建,并且能够实例化不同的类。
但我意识到有一个部分导致了问题我将一个事件调度器传递给了我框架中的许多基类,但是这些类中的每一个都像这样使用调度器:
$this->dispatcher->fire(new FB_Event('FB.Database.Model.beforeUpdate', $this, array('pk' => $pk, 'row' => $row)));
如您所见,我在那里使用了一个new,所以我无法对我的类进行完整的单元测试。我不想将我的应用程序容器传递给所有应用程序,因为在应用程序包含数据库、 session 和其他类不需要的大量服务的实例之后进行调试是一场噩梦。
解决此问题的最佳方法是什么,因为我无法通过依赖注入(inject)传递 FB_Event,因为同一个函数通常会触发 2 个事件:
public function delete($pk) {
$e = $this->dispatcher->fire(new FB_Event('FB.Database.Model.beforeDelete', $this, array('pk' => $pk)));
$pk = $e->params['pk'];
if ($e->preventDefault()) {
return false;
}
$this->requirePK();
list ( $where, $params ) = $this->pkParts(null, $pk);
$sql = "DELETE FROM {$this->name} WHERE $where";
$stm = $this->db->execute($sql, $params);
$this->dispatcher->fire(new FB_Event('FB.Database.Model.afterDelete', $this, array('pk' => $pk)));
return!(bool) $stm->errorCode();
}
我的解决方案之一是向调度程序添加一个名为 fireEvent 的新函数,它将负责创建新的 FB_Event,从而消除各处的耦合。但是会增加 Dispatcher 和 Event 之间的耦合,这样就不那么糟糕了。
public function fireEvent($name, $target, $params = array()) {
return $this->fire(new FB_Event($name, $target, $params = array()));
}
您会在容器中创建某种 EventFactory 并将其传递给 Dispatcher 吗? 消除对像 Event 这样的小对象的依赖是否有点矫枉过正?
谢谢你的建议
最佳答案
我实际上认为您建议的解决方案是最佳答案。你是对的,在代码中实例化一个 FB_Event 是要避免的,因为它很难(-er)测试和耦合你的代码。是的,在您的 fireEvent 方法中,Dispatcher 类和 Event 类之间存在耦合,但 Dispatcher 应该了解 Events,因为它正在调度。是的,耦合是要避免的,但有些类有时确实需要了解其他类;耦合总是不可避免的。您的 fireEvent 方法的好处在于它是一个接缝,因此将来可用于分解代码。
关于带有事件分配器的 PHP 依赖注入(inject)和依赖容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7980126/