简体   繁体   English

Laravel依赖注入/ IOC

[英]Laravel dependency injection / IOC

I'm attempting to integrate to the Xero API - I'm using the following wrapper: 我试图集成到Xero API-我正在使用以下包装器:

https://github.com/drawmyattention/xerolaravel https://github.com/drawmyattention/xerolaravel

I'm able to access the API with the Facade methods but I would really like to resolve the dependencies and do it all properly, I'm still learning these bits. 我可以使用Facade方法访问API,但我真的很想解决依赖关系并正确完成所有工作,但我仍在学习这些内容。

I have followed the instructions, added: 我已按照说明进行了补充:

DrawMyAttention\XeroLaravel\Providers\XeroServiceProvider::class

To my app.php & inside of my Controller I am attempting to resolve this (I think?) 在我的app.php和控制器内部,我正在尝试解决此问题(我认为呢?)

I begin by doing the following: 首先,请执行以下操作:

use DrawMyAttention\XeroLaravel\Providers\XeroServiceProvider as Xero;
    private $xero;


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

And even that, produces the error: 甚至会产生错误:

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

I'm really sorry if this is a stupid question - I haven't dabbled much into this side of Laravel. 如果这是一个愚蠢的问题,我真的很抱歉-我还没有涉足Laravel的这一方面。

The service provider is only used to setup all the bindings and everything for the IOC. 服务提供者仅用于为IOC设置所有绑定和所有内容。 You add it inside your config/app.php , as you mentioned, and then you won't worry about it anymore. 如前所述,将其添加到config/app.php中,然后您就不再担心它了。 This is not the class you should be injecting. 这不是您应该注入的类。

Unfortunately, looking at the code, this package has not set itself up well for dependency injection. 不幸的是,在查看代码时,此程序包无法很好地进行依赖项注入。 This is an example of one of the bindings inside the service provider: 这是服务提供者内部绑定之一的示例:

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

With this binding, that means you can resolve a new PrivateApplication instance out of the IOC by calling $private = app('XeroPrivate'); 使用此绑定,这意味着您可以通过调用$private = app('XeroPrivate');从IOC解析新的PrivateApplication实例$private = app('XeroPrivate'); . However, because PrivateApplication needs special construction (config passed in the constructor), this setup does not help you with dependency injection. 但是,由于PrivateApplication需要特殊的构造(在构造函数中传递的配置),因此此设置无法帮助您进行依赖项注入。

The binding is setup for XeroPrivate , however, this class doesn't exist, which means you can't type hint it to have it injected. 绑定是为XeroPrivate设置的,但是,该类不存在,这意味着您不能键入提示将其注入。 You may have added XeroPrivate as an alias in your config/app.php file, which would bypass the issue of the XeroPrivate class not existing, however this would mean that the facade class is injected (which is what the alias points to), not the PrivateApplication class. 您可能在config/app.php文件中添加了XeroPrivate作为别名,这将绕过XeroPrivate类不存在的问题,但这意味着注入了Facade类(别名指向的是),而不是PrivateApplication类。

In order to be able to properly inject the PrivateApplication class, you will need to setup your own binding. 为了能够正确注入PrivateApplication类,您将需要设置自己的绑定。 You can create a new service provider, or just add this to your AppServiceProvider: 您可以创建一个新的服务提供商,也可以将其添加到您的AppServiceProvider中:

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

You will need to do the same thing for PublicApplication and PartnerApplication : 您将需要对PublicApplicationPartnerApplication做同样的事情:

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

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

With these bindings, you can safely inject any of the classes into your constructor, and they will be resolved properly: 使用这些绑定,您可以安全地将任何类注入到构造函数中,并且可以正确解析它们:

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;
}

When the controller is instantiated, it will see that it needs a new XeroPHP\\Application\\PrivateApplication instance, and it will resolve this instance out of the IOC using the binding we created above (which in turn resolves the XeroPublic object out of the IOC). 实例化控制器后,它将看到它需要一个新的XeroPHP\\Application\\PrivateApplication实例,并将使用上面创建的绑定将这个实例从IOC中解析出来(这又将XeroPublic对象从IOC中解析出来) 。 It will do the same for XeroPHP\\Application\\PublicApplication and XeroPHP\\Application\\PartnerApplication . 它将对XeroPHP\\Application\\PublicApplicationXeroPHP\\Application\\PartnerApplication执行相同的XeroPHP\\Application\\PublicApplication

The rest of the classes don't require any special construction, so there is no need to create custom bindings for them. 其余的类不需要任何特殊的构造,因此无需为其创建自定义绑定。 They can be injected as is: 可以按原样注入它们:

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;
}

When the controller is instantiated, it will see that it needs a new XeroPHP\\Models\\Accounting\\Invoice instance, but since there is no binding in the IOC for this class, it just new s up a new instance and injects that. 实例化控制器后,它将看到它需要一个新的XeroPHP\\Models\\Accounting\\Invoice实例,但是由于IOC中没有此类的绑定,因此它只是new了一个新实例并将其注入。 It will do the same for the rest of the classes shown above. 对于上面显示的其余类,它将执行相同的操作。

Use the alias you've assigned: 使用您分配的别名:

use DrawMyAttention\XeroLaravel\Providers\XeroServiceProvider as Xero;

class Foo {

    private $xero;

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM