我正在尝试集成到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
如果这是一个愚蠢的问题,我真的很抱歉——我对拉拉威尔的这方面没有太多涉猎。
服务提供商仅用于设置IOC的所有绑定和所有内容。正如您所提到的,您可以将它添加到config/app.php
中,这样您就不再担心它了。这不是应该注入的类。
不幸的是,从代码来看,这个包并没有很好地为依赖项注入做好准备。这是服务提供商内部绑定之一的示例:
$this->app->bind('XeroPrivate', function () use ($config) {
return new 'XeroPHP'Application'PrivateApplication($config);
});
使用此绑定,意味着您可以通过调用$private = app('XeroPrivate');
从IOC中解析一个新的PrivateApplication
实例。但是,由于PrivateApplication
需要特殊的构造(构造函数中传递的配置),因此此设置对依赖项注入没有帮助。
绑定是为XeroPrivate
设置的,但是,这个类不存在,这意味着你不能键入hint-it来注入它。您可能已经在config/app.php
文件中添加了XeroPrivate
作为别名,这将绕过XeroPrivate
类不存在的问题,但这意味着注入了facade类(这就是别名所指向的),而不是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中解析该实例(这反过来又从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
建立一个新实例并注入它。它将对上面显示的其余类执行相同的操作。
使用您指定的别名:
use DrawMyAttention'XeroLaravel'Providers'XeroServiceProvider as Xero;
class Foo {
private $xero;
public function __construct(Xero $xero)
{
$this->xero = $xero;
}
}