I'm attempting to integrate to the Xero API - I'm using the following wrapper:
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.
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?)
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.
The service provider is only used to setup all the bindings and everything for the IOC. You add it inside your config/app.php
, as you mentioned, and then you won't worry about it anymore. 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');
. However, because PrivateApplication
needs special construction (config passed in the constructor), this setup does not help you with dependency injection.
The binding is setup for XeroPrivate
, however, this class doesn't exist, which means you can't type hint it to have it injected. 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.
In order to be able to properly inject the PrivateApplication
class, you will need to setup your own binding. You can create a new service provider, or just add this to your AppServiceProvider:
$this->app->bind('XeroPHP\Application\PrivateApplication', function ($app) {
return $app['XeroPrivate'];
});
You will need to do the same thing for PublicApplication
and PartnerApplication
:
$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). It will do the same for XeroPHP\\Application\\PublicApplication
and XeroPHP\\Application\\PartnerApplication
.
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. 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;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.