【问题标题】:Laravel: Binding to IoC ContainerLaravel:绑定到 IoC 容器
【发布时间】:2014-06-24 22:50:52
【问题描述】:

如果你将一个类绑定到 IoC...

App::bind('Thing', function() {
    return new \ThingOne;
});

然后,ThingOne 对象将永远被实例化,除非您调用 App::make('Thing')。这是一件好事。

但是,如果您尝试覆盖该绑定:

App::bind('Thing', function() {
    return new \ThingOne;
});
App::bind('Thing', function() {
    return new \ThingTwo;
});
App::bind('Thing', function() {
    return new \ThingThree;
});

...然后ThingTwo 对象和ThingThree 对象将被实例化(并调用它们的构造函数),即使您从未调用过App::make('Thing')!这是一件坏事!为什么,以及如何防止这种情况发生?如果不允许我们覆盖绑定以便我们可以扩展包之类的东西,那么 IoC 的用途是什么? (这就是我想做的:将类绑定到我的包中的 IoC,然后在其他项目中实现这些包时选择性地覆盖它们。)

顺便说一句,无论您使用bind() 还是singleton(),都会发生这种情况,没有区别。

非常感谢您的指导。

【问题讨论】:

  • 在重新绑定对象之前是否尝试过调用 App::offsetUnset('Thing')?
  • @FractalizeR 我没有 - 确实有效,谢谢!

标签: php class laravel inversion-of-control


【解决方案1】:

问题似乎出在rebound 方法中的Illuminate\Container\Container。从逻辑上讲,该方法仅在重新绑定时才被调用,因此它不是第一次调用,而是在以后调用。您可以看到实例是为准备反弹回调而创建的。

/**
 * Fire the "rebound" callbacks for the given abstract type.
 *
 * @param  string  $abstract
 * @return void
 */
protected function rebound($abstract)
{
    $instance = $this->make($abstract);

    foreach ($this->getReboundCallbacks($abstract) as $callback)
    {
        call_user_func($callback, $this, $instance);
    }
}

FractalizeR 是对的,在再次绑定之前调用App::offsetUnset('Thing') 不会调用 __construct 方法。

【讨论】:

  • 啊,我明白了。感谢您抽出宝贵时间 dwenaus,感谢您和 Fractilize 提供的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-10
  • 1970-01-01
  • 2017-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多