2016-04-05 5 views
1

Ich versuche, mehrere Dienste zu erstellen, die alle die gleiche Schnittstelle/Vertrag implementieren, und welcher Dienst verwendet wird, hängt von Benutzereingaben ab. So kann ich das im Controller tun, um Service zu erhalten, der vom Benutzer vorgewählt wird.Mehrere Dienste implementieren die gleiche Schnittstelle, zur Laufzeit wechseln

Dienstanbieter:

/** 
* Register the application services. 
* 
* @return void 
*/ 
public function register() 
{ 
    $this->app->call([$this, 'registerProductionService']); 
} 

/** 
* Produce video depend on user selection. 
* 
* @param Request $request 
*/ 
public function registerProductionService(Request $request) 
{ 
    $service = studly_case($request->input('production')) . 'Repository'; 

    if (in_array($service, $this->availableServices)) 
    { 
     $namespace = (new \ReflectionClass(ReportContract::class))->getNamespaceName(); 

     $this->app->bind(ReportContract::class, "{$namespace}\\{$service}"); 
    } 
} 

In Controller:

public function create(ReportContract $report) 
{ 
    $report->create(); 
} 

Aber wenn ich() -Methode aus der Warteschlange erstellen anrufen möchten, kann ich keine Daten von Anfrage-Klasse erhalten. Es bedeutet, dass ich keinen Service erhalten kann, der vom Benutzer ausgewählt wurde? Wie kann ich das tun?

+1

Es ist eine gute Frage, aber ich denke nicht, dass Sie es zur Laufzeit mit Laravel-Diensten tun können, die im Dienstanbieter registriert sind. Das muss zur Bootstrap-Zeit geladen werden. Möglicherweise können Sie in der Middleware etwas Ähnliches erreichen - die Middleware hat Zugriff auf Ihr Anfrageobjekt und sollte daher in der Lage sein, eine Bindung zwischen der Schnittstelle und der Implementierung zu initiieren. – delatbabel

+0

Ich kann mit Middleware nicht herausfinden. Kannst du mir ein Beispiel geben? Vielen Dank !!! – user3118789

Antwort

1

Sie können ihn binden mit einem Rückruf:

$this->app->bind(ReportContract::class, function($app) { 
    $request = $app['request']; 

    $service = studly_case($request->input('production')) . 'Repository'; 

    if (in_array($service, $this->availableServices)) 
    { 
     $namespace = (new \ReflectionClass(ReportContract::class))->getNamespaceName(); 

     return $app->make("{$namespace}\\{$service}"); 
    } 
}); 

Sie könnten allerdings eine Standard zurückkehren möchten.

+0

Es kann nicht funktionieren, die $ request-> all() gibt immer leere Array zurück. – user3118789

Verwandte Themen