Какая разница между App:: singleton и bindShared?

В документах Laravel указывается, что соответствующий способ привязки singleton имеет метод App::singleton(), но внутри Laravel будет использовать метод bindShared() (например, в TranslationServiceProvider).

Я предполагаю, что документированный подход является предпочтительным, но есть ли функциональная разница? Если нет, есть ли причина иметь два подхода (за исключением, возможно, исторической аварии)?

Ответ 1

Мне было интересно то же самое. Я не знаю мотивов этого, но я могу говорить с несколькими отличиями.

Вот определение двух методов из Laravel 4.2:

public function singleton($abstract, $concrete = null)
{
    $this->bind($abstract, $concrete, true);
}

public function bindShared($abstract, Closure $closure)
{ 
    $this->bind($abstract, $this->share($closure), true);
}

Сходства:

  • Оба метода называют bind() под капотом.
  • Оба метода передают true третьему параметру bind(), что означает, что это общий объект.
  • В обоих случаях, поскольку это общий объект, вызов isShared($abstract) возвращает true.
  • В обоих случаях, поскольку это общий объект, вызов make($abstract) возвращает только первый экземпляр.

Отличия:

  • singleton() примет значение Closure или string. bindShared() принимает только Closure, а не string.
  • bindShared(), в дополнение к привязке объекта к контейнеру IOC как общему объекту, берет дополнительный этап обертывания прошедшего Closure в share 'd Closure, который предотвращает передачу Closure от выполнения более одного раза. На первый взгляд это кажется двойной гарантией того, что объект будет рассматриваться как одноэлементный. Я могу только догадываться, почему это может быть желательно.
  • bindShared() вызывается 87 раз внутри рамки. singleton() называется 0 раз.

Ответ 2

Они (функционально идентичны), за исключением того, что bindShared() принимает только замыкания.

Таким образом, bindShared() устарел в Laravel 5.1 (PR 9009 - commit 829060f) и удален в Laravel 5.2 (PR 9037).

Дело окончательно решено:)

Ответ 3

bind ($ abstract, $specific, $shared) Добавляет $abstract в качестве ключа к контейнеру, причем $конкретным является конкретный класс для создания экземпляра на своем месте. В основном используется для обеспечения конкретной реализации интерфейса.

доля ($ закрытия) Учитывая закрытие (только), он действует так, как будто он был общим (стиль экземпляра /singleton ) и возвращает его. Технически эквивалентно App:: bind ($ key, $clos, true), но идет об этом по-другому. В основном используется в поставщиках услуг для добавления полностью разрешаемой службы в контейнер IoC.

bindShared ($ abstract, $закрытия) Ярлык, который был введен в 4.1, который соответствует общей схеме. По существу помогает тем, кто хочет привязать общий экземпляр в контейнере. См. Ниже, например.

singleton ($ abstract, $specific) Просто псевдоним, связанный с $shared аргументом, установленным в true. В основном используется для обеспечения конкретной реализации интерфейса, но в нем должен быть только один экземпляр (соединение с базой данных и т.д.).

Это от http://alexrussell.me.uk/laravel-cheat-sheet/ Я думаю, что эта ссылка должна быть полезной

Ответ 4

Я думаю, в основном, для обратной совместимости. Синглтон объясняет лучшее поведение, чем bindShared. Удаление bindShared означает, что разработчики пакетов реорганизуют свой код.