Инъекция зависимости Laravel / IOC

Я пытаюсь интегрироваться в Xero API — я использую следующую оболочку:

https://github.com/drawmyattention/xerolaravel

Я могу получить доступ к API с помощью методов Facade, но я действительно хотел бы разрешить зависимости и сделать все правильно, я все еще изучаю эти биты.

Я следовал инструкциям, добавил:

DrawMyAttention\XeroLaravel\Providers\XeroServiceProvider::class

На мой app.php & внутри моего контроллера я пытаюсь решить эту проблему (я думаю?)

Я начинаю с того, что делаю следующее:

use DrawMyAttention\XeroLaravel\Providers\XeroServiceProvider as Xero;
private $xero;public function __construct(XeroServiceProvider $xero)
{
$this->xero = $xero;
}

И даже это выдает ошибку:

 BindingResolutionException in Container.php line 828:
Unresolvable dependency resolving [Parameter #0 [ <required> $app ]]
in class Illuminate\Support\ServiceProvider

Мне очень жаль, если это глупый вопрос — я не слишком увлекался этой стороной Ларавела.

0

Решение

Поставщик услуг используется только для настройки всех привязок и всего для IOC. Вы добавляете это в свой config/app.php, как вы упомянули, и тогда вы больше не будете об этом беспокоиться. Это не тот класс, который вы должны вводить.

К сожалению, глядя на код, этот пакет не очень хорошо настроен для внедрения зависимостей. Это пример одной из привязок внутри поставщика услуг:

$this->app->bind('XeroPrivate', function () use ($config) {
return new \XeroPHP\Application\PrivateApplication($config);
});

С этим связыванием это означает, что вы можете решить новый PrivateApplication экземпляр из МОК, позвонив $private = app('XeroPrivate');, Тем не менее, потому что PrivateApplication требуется специальная конструкция (конфиг передается в конструкторе), эта настройка не поможет вам с внедрением зависимостей.

Привязка настроена для XeroPrivateоднако, этот класс не существует, что означает, что вы не можете напечатать подсказку, чтобы он был введен. Вы, возможно, добавили XeroPrivate как псевдоним в вашем config/app.php файл, который бы обойти проблему XeroPrivate класс не существует, однако это будет означать, что вводится класс фасада (на что указывает псевдоним), а не PrivateApplication учебный класс.

Для того, чтобы иметь возможность правильно вводить PrivateApplication класс, вам нужно будет установить собственную привязку. Вы можете создать нового поставщика услуг или просто добавить его в свой AppServiceProvider:

$this->app->bind('XeroPHP\Application\PrivateApplication', function ($app) {
return $app['XeroPrivate'];
});

Вам нужно будет сделать то же самое для PublicApplication а также PartnerApplication:

$this->app->bind('XeroPHP\Application\PublicApplication', function ($app) {
return $app['XeroPublic'];
});

$this->app->bind('XeroPHP\Application\PartnerApplication', function ($app) {
return $app['XeroPartner'];
});

С помощью этих привязок вы можете безопасно внедрить любой из классов в ваш конструктор, и они будут разрешены правильно:

use XeroPHP\Application\PrivateApplication;
use XeroPHP\Application\PublicApplication;
use XeroPHP\Application\PartnerApplication;

public function __construct(PrivateApplication $xeroPrivate, PublicApplication $xeroPublic, PartnerApplication $xeroPartner)
{
$this->xeroPrivate = $xeroPrivate;
$this->xeroPublic = $xeroPublic;
$this->xeroPartner = $xeroPartner;
}

Когда будет создан экземпляр контроллера, он увидит, что ему нужен новый XeroPHP\Application\PrivateApplication экземпляр, и он разрешит этот экземпляр из IOC, используя привязку, которую мы создали выше (которая, в свою очередь, разрешает XeroPublic объект вне МОК). Это будет делать то же самое для XeroPHP\Application\PublicApplication а также XeroPHP\Application\PartnerApplication,

Остальные классы не требуют какой-либо специальной конструкции, поэтому нет необходимости создавать собственные привязки для них. Их можно вводить как есть:

use XeroPHP\Models\Accounting\Invoice;
use XeroPHP\Models\Accounting\Invoice\LineItem;
use XeroPHP\Models\Accounting\Contact;
use XeroPHP\Models\Accounting\BrandingTheme;
use XeroPHP\Models\Accounting\Attachment;

public function __construct(Invoice $xeroInvoice, LineItem $xeroLineItem, Contact $xeroContact, BrandingTheme $xeroBrandingTheme, Attachment $xeroAttachment)
{
$this->xeroInvoice = $xeroInvoice;
$this->xeroLineItem = $xeroLineItem;
$this->xeroContact = $xeroContact;
$this->xeroBrandingTheme = $xeroBrandingTheme;
$this->xeroAttachment = $xeroAttachment;
}

Когда будет создан экземпляр контроллера, он увидит, что ему нужен новый XeroPHP\Models\Accounting\Invoice экземпляр, но поскольку в IOC нет привязки для этого класса, он просто newСоздает новый экземпляр и внедряет его. Это сделает то же самое для остальных классов, показанных выше.

1

Другие решения

Используйте назначенный вами псевдоним:

use DrawMyAttention\XeroLaravel\Providers\XeroServiceProvider as Xero;

class Foo {

private $xero;

public function __construct(Xero $xero)
{
$this->xero = $xero;
}

}
0

По вопросам рекламы [email protected]