2016-03-30 19 views
0

Ich versuche, auf die Xero API zu integrieren - ich bin mit dem folgenden Wrapper:Laravel Dependency Injection/IOC

https://github.com/drawmyattention/xerolaravel

Ich bin in der Lage, die API mit den Fassaden Methoden zuzugreifen, aber ich würde gerne die Abhängigkeiten auflösen und alles richtig machen, ich lerne immer noch diese Bits.

Ich habe die Anweisungen befolgt, fügte hinzu:

DrawMyAttention\XeroLaravel\Providers\XeroServiceProvider::class 

Zu meiner app.php & Innenseite meines Controllers Ich versuche, dieses Problem zu beheben (ich glaube?)

Ich beginne damit, wie folgt vorgehen :

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


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

Und das selbst erzeugt den Fehler:

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

Es tut mir wirklich leid, wenn das eine dumme Frage ist - ich habe mich nicht viel in diese Seite von Laravel eingemischt.

+0

Entfernen Sie 'as Xero' oder ändern Sie Ihren Konstruktor zu' Xero $ xero'. – jardis

Antwort

1

Der Service-Provider nur die Einrichtung verwendet wird, alle Bindungen und alles für das IOC. Sie fügen es in Ihre config/app.php, wie Sie erwähnt haben, und dann machen Sie sich keine Sorgen mehr darüber. Dies ist nicht die Klasse, die Sie injizieren sollten.

Unglücklicherweise hat sich dieses Paket für die Abhängigkeitsinjektion nicht gut eingestellt. Dies ist ein Beispiel für eine der Bindungen innerhalb des Dienstleisters:

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

Mit dieser Bindung, die bedeutet, dass Sie eine neue PrivateApplication Instanz aus dem IOC $private = app('XeroPrivate'); durch den Aufruf auflösen können. Da PrivateApplication jedoch eine spezielle Konstruktion benötigt (config im Konstruktor übergeben), hilft dieses Setup nicht bei der Abhängigkeitsinjektion.

Die Bindung ist für XeroPrivate eingerichtet, jedoch existiert diese Klasse nicht, was bedeutet, dass Sie nicht Tipp eingeben können, um es injiziert zu haben. Sie haben möglicherweise XeroPrivate als Alias ​​in Ihrer config/app.php Datei hinzugefügt, die das Problem der XeroPrivate Klasse nicht bestehen würde, aber dies würde bedeuten, dass die Fassade Klasse injiziert wird (was der Alias ​​zeigt), nicht die PrivateApplication Klasse.

Um die Klasse PrivateApplication ordnungsgemäß einspeisen zu können, müssen Sie eine eigene Bindung einrichten.Sie können einen neuen Service Provider erstellen oder diese zu Ihrem AppServiceProvider hinzufügen:

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

Sie müssen die gleiche Sache für PublicApplication und PartnerApplication tun:

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

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

Mit diesen Bindungen können Sie sicher eine der Klassen in Ihrem Konstruktor injizieren, und sie werden richtig aufgelöst werden:

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

Wenn der Controller instanziiert wird, wird es sehen Sie, dass es eine neue XeroPHP\Application\PrivateApplication Instanz benötigt, und es löst diese Instanz aus dem IOC mit der Bindung, die wir oben erstellt haben (die wiederum löst das XeroPublic Objekt aus dem IOC). Es wird das gleiche für XeroPHP\Application\PublicApplication und XeroPHP\Application\PartnerApplication tun.

Der Rest der Klassen erfordert keine spezielle Konstruktion, sodass keine benutzerdefinierten Bindungen für sie erstellt werden müssen. Sie können injiziert werden, wie:

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

Wenn der Controller instanziiert wird, wird es sehen, dass es eine neue XeroPHP\Models\Accounting\Invoice Instanz braucht, aber da es in der IOC für diese Klasse keine Bindung, es ist nur new s up a neue Instanz und injiziert das. Das Gleiche gilt für den Rest der oben gezeigten Klassen.

+1

Beeindruckende Antwort. Du hast mir wirklich geholfen, es herauszufinden und zu verstehen, was vor sich ging. Danke für die Mühe, die du durchgemacht hast! – ExohJosh

0

Verwenden Sie den Alias, den Sie zugewiesen haben:

use DrawMyAttention\XeroLaravel\Providers\XeroServiceProvider as Xero; 

class Foo { 

    private $xero; 

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

}