【问题标题】:Laravel dependency injection / IOCLaravel 依赖注入/IOC
【发布时间】:2016-07-19 03:04:24
【问题描述】:

我正在尝试集成到 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 的这一方面。

【问题讨论】:

  • 删除 as Xero 或将您的构造函数更改为 Xero $xero

标签: php laravel ioc-container xero-api


【解决方案1】:

服务提供者仅用于为 IOC 设置所有绑定和一切。正如您所提到的,您将它添加到您的config/app.php 中,然后您将不再担心它。这不是你应该注入的类。

不幸的是,查看代码,这个包并没有为依赖注入做好准备。这是服务提供者内部绑定之一的示例:

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

使用此绑定,这意味着您可以通过调用 $private = app('XeroPrivate'); 从 IOC 中解析一个新的 PrivateApplication 实例。但是,因为PrivateApplication 需要特殊的构造(配置在构造函数中传递),所以这种设置对依赖注入没有帮助。

绑定是为XeroPrivate 设置的,但是,这个类不存在,这意味着你不能输入提示来注入它。您可能在您的config/app.php 文件中添加了XeroPrivate 作为别名,这将绕过XeroPrivate 类不存在的问题,但这意味着外观类被注入(这是别名所指向的) ,而不是 PrivateApplication 类。

为了能够正确注入PrivateApplication 类,您需要设置自己的绑定。您可以创建一个新的服务提供者,或者只是将其添加到您的 AppServiceProvider:

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

您需要为PublicApplicationPartnerApplication 做同样的事情:

$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\PublicApplicationXeroPHP\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 中没有为此类绑定,它只是 news 建立一个新实例并注入它。对于上面显示的其余类,它将执行相同的操作。

【讨论】:

  • 令人印象深刻的答案。你真的帮助我弄清楚并了解发生了什么。感谢您所付出的努力!
【解决方案2】:

使用您分配的别名:

use DrawMyAttention\XeroLaravel\Providers\XeroServiceProvider as Xero;

class Foo {

    private $xero;

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

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 2016-11-13
    • 2019-06-25
    • 1970-01-01
    • 2010-10-12
    • 1970-01-01
    相关资源
    最近更新 更多