为什么 laravel IoC 不使用我的方法配置我的 class?

Why does laravel IoC does not provisioning my class with my method?

我不明白为什么 laravel 试图在不使用我的方法的情况下自行创建我的 class。我可以看到执行了 IoC 绑定(显示了 POINT 1)。但是单例方法永远不会被执行。为什么?

在我的服务提供商中(未延期):

/**
 * Register the service provider.
 *
 * @return void
 */
public function register()
{
    echo "POINT 1"; // I can see this one
    $this->app->singleton(\App\Services\FooBar::class, function($app)
    {
        echo "POINT 2\n"; // Does not comes here
        return new FooBar($params);
    });
}

我在创建 class 时尝试使用类型提示来解决依赖关系:

class Test
{
    public function __construct(FooBar $fooBar)
    {

    }
}

我看到 laravel 试图创建 FooBar 来注入它,但无法解析 FooBar 的依赖项。如果 laravel 会调用服务提供商回调,则它们可以得到解决,但事实并非如此。为什么?如何让 laravel 为那个 class 使用那个回调?

这是因为当您将 class 绑定到 IoC 容器时,您并没有立即调用闭包。相反,当您需要对容器中的 class 执行一些操作时,您调用 App::make('class') 将触发闭包并为您提供从中返回的值。例如

/**
 * Register the service provider.
 *
 * @return void
 */
public function register()
{
    echo "POINT 1"; // I can see this one
    $this->app->singleton(\App\Services\FooBar::class, function($app)
    {
        echo "POINT 2\n"; // Does not comes here
        return new FooBar($params);
    });

    $this->app->make(\App\Services\FooBar::class); //here POINT 2 will be called first.
}

使用 boot() 方法来启动您的服务,而不是关闭(那是行不通的)。

/**
 * @param \App\Services\FooBar $foobar
 */
public function boot(\App\Services\FooBar $foobar)
{
    $foobar->setOptions(['option' => 'value']);
}

它将在服务实例化后立即启动。