Laravel 如何延迟在单个服务提供者中列出的多个绑定?

pro*_*mer 4 php deferred-loading service-provider laravel laravel-5

我希望我的所有存储库都列在一个服务提供商中,但我希望它们一次全部加载...

考虑以下服务提供商:

class RepositoryServiceProvider extends ServiceProvider {

    protected $defer = true;

    public function register()
    {
        $this->app->bind(
            'App\Repositories\Contracts\FooRepository',
            'App\Repositories\SQL\FooSQLRepository');

        $this->app->bind(
            'App\Repositories\Contracts\BarRepository',
            'App\Repositories\SQL\BarSQLRepository');

        // and more to be added later...
    }

    public function provides()
    {

        // Will it defer and load all these at once? Or only the one(s) needed?
        return ['App\Repositories\Contracts\FooRepository',
                'App\Repositories\Contracts\BarRepository'];
    }

}
Run Code Online (Sandbox Code Playgroud)

根据 Laravel 文档,我可以将绑定的注册推迟到需要时。但是,当我在单个服务提供者中添加多个绑定时,这是否有效?具体来说,我的意思是,它会推迟然后加载所有还是加载需要的

luk*_*ter 5

Laravel 将注册所有绑定,即使只需要一个。延迟功能实际上非常简单。首先,provides()创建条目和实际提供者的映射:

Illuminate\Foundation\ProviderRepository@compileManifest

if ($instance->isDeferred())
{
    foreach ($instance->provides() as $service)
    {
        $manifest['deferred'][$service] = $provider;
    }
    $manifest['when'][$provider] = $instance->when();
}
Run Code Online (Sandbox Code Playgroud)

然后什么时候make()调用Illuminate\Foundation\Application...

if (isset($this->deferredServices[$abstract]))
{
    $this->loadDeferredProvider($abstract);
}
Run Code Online (Sandbox Code Playgroud)

...并且绑定匹配延迟提供程序之一,它将在此处结束:

Illuminate\Foundation\Application@registerDeferredProvider

$this->register($instance = new $provider($this));

if ( ! $this->booted)
{
    $this->booting(function() use ($instance)
    {
        $this->bootProvider($instance);
    });
}
Run Code Online (Sandbox Code Playgroud)

正如您可能知道的那样,现在提供程序像往常一样注册,这意味着register()boot()被调用。如果您考虑一下,甚至不可能从服务提供者加载一个绑定而不包含其他绑定,因为这一切都是在一种方法中完成的。

  • 这个答案让我很伤心,因为现在我需要为每个存储库创建一个服务提供者(因为我不想同时加载所有这些) (2认同)
  • 我处于完全相同的情况。如果 bind 方法上有一个标志,那就太好了。也许是 PR 的时候了 :) (2认同)