Связывать зависимость поставщика услуг Laravel внутри самого поставщика? - PullRequest
0 голосов
/ 25 июня 2018

Я только начинаю понимать поставщиков услуг и контейнер IoC, однако меня смущает одна вещь.У меня есть SpamServiceProvider, который требует двух других классов для функционирования.Однако один из этих классов, InvalidKeywords, имеет параметр массива $ blacklist, который необходимо передать его конструктору.

Если я зарегистрирую этот класс в AppServiceProvider и передам массив $ blacklist, все будет работать нормально.Однако, если я попытаюсь связать класс в SpamServiceProvider, он не будет вставлять черный список в конструктор InvalidKeywords.

Так что я думаю, что мой вопрос - почему это так?И есть ли способ сохранить такие привязки вместе в одном контейнере или мне просто нужно связать InvalidKeywords внутри AppServiceProvider?

Это работает

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 голосов
/ 25 июня 2018

Во втором случае вы не разрешаете класс InvalidKeywords из контейнера, просто создаете новый экземпляр.Вместо этого попробуйте использовать помощники app или resolve при создании SpamManager:

$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'));
});
...