Laravel:绑定到IoC Container

Len*_*eng 5 php class inversion-of-control laravel

如果将类绑定到IoC ...

App::bind('Thing', function() {
    return new \ThingOne;
});
Run Code Online (Sandbox Code Playgroud)

然后,除非您调用,否则永远不会实例化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;
});
Run Code Online (Sandbox Code Playgroud)

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

顺便说一句,这种情况无论使用bind()还是singleton()没什么区别.

非常感谢您的任何指导.

dwe*_*aus 4

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

/**
 * 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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