Laravel依赖注入/IOC
Laravel dependency injection / IOC
我正在尝试集成到 Xero API - 我正在使用以下包装器:
https://github.com/drawmyattention/xerolaravel
我可以使用 Facade 方法访问 API,但我真的很想解决依赖关系并正确地完成所有操作,我仍在学习这些内容。
我已按照说明添加:
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
如果这是一个愚蠢的问题,我真的很抱歉 - 我没有涉足 Laravel 的这一方面。
使用您指定的别名:
use DrawMyAttention\XeroLaravel\Providers\XeroServiceProvider as Xero;
class Foo {
private $xero;
public function __construct(Xero $xero)
{
$this->xero = $xero;
}
}
服务提供商仅用于为 IOC 设置所有绑定和所有内容。正如您提到的,您将它添加到 config/app.php
中,然后您就不会再担心了。这不是您应该注入的 class。
不幸的是,查看代码,这个包没有为依赖注入做好自身设置。这是服务提供商内部绑定之一的示例:
$this->app->bind('XeroPrivate', function () use ($config) {
return new \XeroPHP\Application\PrivateApplication($config);
});
有了这个绑定,这意味着您可以通过调用 $private = app('XeroPrivate');
从 IOC 中解析一个新的 PrivateApplication
实例。但是,由于PrivateApplication
需要特殊构造(在构造函数中传递的配置),此设置无法帮助您进行依赖注入。
已为 XeroPrivate
设置绑定,但是,此 class 不存在,这意味着您无法键入提示以将其注入。您可能在 config/app.php
文件中添加了 XeroPrivate
作为别名,这将绕过 XeroPrivate
class 不存在的问题,但是这意味着外观 class 被注入(这是别名指向的),而不是 PrivateApplication
class.
为了能够正确注入 PrivateApplication
class,您需要设置自己的绑定。您可以创建一个新的服务提供者,或者将其添加到您的 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'];
});
使用这些绑定,您可以安全地将任何 class 注入您的构造函数,它们将被正确解析:
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
IOC 之外的对象)。它会对 XeroPHP\Application\PublicApplication
和 XeroPHP\Application\PartnerApplication
执行相同的操作。
其余 classes 不需要任何特殊构造,因此无需为它们创建自定义绑定。它们可以按原样注入:
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 中没有绑定这个 class,它只是 new
创建一个新实例并注入它。它将对上面显示的其余 classes 执行相同的操作。
我正在尝试集成到 Xero API - 我正在使用以下包装器:
https://github.com/drawmyattention/xerolaravel
我可以使用 Facade 方法访问 API,但我真的很想解决依赖关系并正确地完成所有操作,我仍在学习这些内容。
我已按照说明添加:
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
如果这是一个愚蠢的问题,我真的很抱歉 - 我没有涉足 Laravel 的这一方面。
使用您指定的别名:
use DrawMyAttention\XeroLaravel\Providers\XeroServiceProvider as Xero;
class Foo {
private $xero;
public function __construct(Xero $xero)
{
$this->xero = $xero;
}
}
服务提供商仅用于为 IOC 设置所有绑定和所有内容。正如您提到的,您将它添加到 config/app.php
中,然后您就不会再担心了。这不是您应该注入的 class。
不幸的是,查看代码,这个包没有为依赖注入做好自身设置。这是服务提供商内部绑定之一的示例:
$this->app->bind('XeroPrivate', function () use ($config) {
return new \XeroPHP\Application\PrivateApplication($config);
});
有了这个绑定,这意味着您可以通过调用 $private = app('XeroPrivate');
从 IOC 中解析一个新的 PrivateApplication
实例。但是,由于PrivateApplication
需要特殊构造(在构造函数中传递的配置),此设置无法帮助您进行依赖注入。
已为 XeroPrivate
设置绑定,但是,此 class 不存在,这意味着您无法键入提示以将其注入。您可能在 config/app.php
文件中添加了 XeroPrivate
作为别名,这将绕过 XeroPrivate
class 不存在的问题,但是这意味着外观 class 被注入(这是别名指向的),而不是 PrivateApplication
class.
为了能够正确注入 PrivateApplication
class,您需要设置自己的绑定。您可以创建一个新的服务提供者,或者将其添加到您的 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'];
});
使用这些绑定,您可以安全地将任何 class 注入您的构造函数,它们将被正确解析:
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
IOC 之外的对象)。它会对 XeroPHP\Application\PublicApplication
和 XeroPHP\Application\PartnerApplication
执行相同的操作。
其余 classes 不需要任何特殊构造,因此无需为它们创建自定义绑定。它们可以按原样注入:
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 中没有绑定这个 class,它只是 new
创建一个新实例并注入它。它将对上面显示的其余 classes 执行相同的操作。