在提供程序本身内部绑定Laravel服务提供程序的依赖项?

时间:2018-06-25 06:19:44

标签: php laravel dependency-injection ioc-container

我刚刚开始迷惑服务提供商和IoC容器,但是有一件事让我感到困惑。我有一个SpamServiceProvider,它需要另外两个类才能起作用。但是,其中一个类InvalidKeywords具有数组$ blacklist参数,该参数需要传递给其构造函数。

如果我在AppServiceProvider中注册该类并传递$ blacklist数组,则一切正常。但是,如果我尝试在SpamServiceProvider中绑定该类,则不会将$ blacklist注入InvalidKeywords构造函数中。

所以我想我的问题是为什么呢?有没有办法将这样的绑定保持在单个容器中,还是我只需要在AppServiceProvider内部绑定InvalidKeywords?

这有效

class SpamServiceProvider extends ServiceProvider
{

/**
 * Indicates if loading of the provider is deferred.
 *
 * @var bool
 */
protected $defer = true;

/**
 * Bootstrap services.
 *
 * @return void
 */
public function boot()
{
    //
}

/**
 * Register services.
 *
 * @return void
 */
public function register()
{

    $this->app->bind(SpamManager::class, function ($app) {
        return new SpamManager(new InvalidKeywords, new RepeatedCharacters);
    });
}

}


class AppServiceProvider extends ServiceProvider
{
/**
 * Register any application services.
 *
 * @return void
 */
public function register()
{
    $this->app->bind(InvalidKeywords::class, function ($app) {
        return new InvalidKeywords(config('spam.blacklist'));
    });
}
}

这不起作用

class SpamServiceProvider extends ServiceProvider
{

/**
 * Indicates if loading of the provider is deferred.
 *
 * @var bool
 */
protected $defer = true;

/**
 * Bootstrap services.
 *
 * @return void
 */
public function boot()
{
    //
}

/**
 * Register services.
 *
 * @return void
 */
public function register()
{

    $this->app->bind(InvalidKeywords::class, function ($app) {
        return new InvalidKeywords(config('spam.blacklist'));
    });

    $this->app->bind(SpamManager::class, function ($app) {
        return new SpamManager(new InvalidKeywords, new RepeatedCharacters);
    });
}
}

1 个答案:

答案 0 :(得分:1)

在第二种情况下,您不是从容器中解析InvalidKeywords类,而只是创建一个新实例。相反,在创建app时尝试使用resolveSpamManager助手:

$this->app->bind(SpamManager::class, function ($app) {
    return new SpamManager(resolve(InvalidKeywords::class), resolve(RepeatedCharacters::class));
});

// or 
$this->app->bind(SpamManager::class, function ($app) {
    return new SpamManager(app(InvalidKeywords::class), app(RepeatedCharacters::class));
});

我也会用InvalidKeywords创建一个单例:

$this->app->singleton(InvalidKeywords::class, function ($app) {
    return new InvalidKeywords(config('spam.blacklist'));
});