2014-10-21 19 views
6

Zmieniam kontrolery i klasy pomocników, aby użyć wtrysku zależności, i wygląda na to, że moje klasy pomocnicze utknęły w nieskończonej pętli.Zastrzyk zależności na niestandardowych klasach utknął w nieskończonej pętli w L4.2?

Poniżej znajduje się mój niestandardowy ServiceProvider i dwie przykładowe klasy pomocnicze. Jak widać, wstrzykują się nawzajem, więc idą tam iz powrotem.

Jakie jest rozwiązanie tego problemu? Jaki błąd wydaje mi się robić? Co mogę zrobić, aby móc wykonywać testy na klasach pomocniczych, takich jak General i Person, podczas kpiąc z klas pomocniczych, które są wywoływane z ich wnętrza?

Jednym ze sposobów, które myślę, że może pracować w moim ServiceProvider, wykonaj następujące czynności:

if (isset($appmade->General)) { 
    // inject the General app that's already instantiated 
} else { 
    $abc = app::make('\Lib\MyOrg\General'); 
    $appmade->General = $abc; 
} 

Czy to jest poprawny sposób?

// /app/providers/myorg/MyOrgServiceProvider.php 

namespace MyOrg\ServiceProvider; 
use Illuminate\Support\ServiceProvider; 
class MyOrgServiceProvider extends ServiceProvider 
{ 
    public function register() 
    { 
     $this->app->bind('\Lib\MyOrg\General', function ($app) { 
      return new \Lib\MyOrg\General(
       $app->make('\Lib\MyOrg\Person'), 
       $app->make('\App\Models\User') 
      ); 
     }); 

     $this->app->bind('\Lib\MyOrg\Person', function ($app) { 
      return new \Lib\MyOrg\Person(
       $app->make('\Lib\MyOrg\General'), 
       $app->make('\App\Models\Device') 
      ); 
     }); 
    } 
} 

// /app/libraries/myorg/general.php 

namespace Lib\MyOrg; 
use App\Models\User; 
use Lib\MyOrg\Person; 
class General 
{ 
    protected $model; 
    protected $class; 

    public function __construct(Person $personclass, User $user) 
    { 
    } 
} 

// /app/libraries/myorg/person.php 

namespace Lib\MyOrg; 
use App\Models\Device; 
use Lib\MyOrg\General; 
class Person 
{ 
    protected $model; 
    protected $class; 

    public function __construct(General $generalclass, Device $device) 
    { 
    } 
} 
+0

Czy uważasz, że kod jest właściwie wcięty? – hek2mgl

+0

@ hek2mgl Czy odnosisz się do sposobu wyświetlania kodu w pytaniu? Wygląda dobrze dla mnie ... proszę przesłać edycję, jeśli masz sugestie czytelności –

+0

@John To nie jest dobre. Wcale nie w porządku. Musisz zreorganizować swoje zajęcia. Unikaj zależności cyklicznej. – brainless

Odpowiedz

10

Twoje zajęcia pomocnicze mają sprawę okrągłej uzależnienia, które po zmieszaniu z wstrzykiwania zależności, należy je un-chwilowe ... i nie ma dobry sposób, aby zachęcić ich do pracy i być łatwo sprawdzalne.

Istnieją pewne hack-y sposoby, aby to działało:

Cykliczne zależność zwykle wskazuje, że zmiana projektu jest w porządku, a najlepiej rozwiązany przez ponowne rozważenie jak twoi klas współdziałać ze sobą.

  • Jeśli osoba i zajęcia ogólne całkowicie od siebie zależne, a następnie to możliwe dzielą jeden odpowiedzialność i powinien być połączone w jedną klasę.

  • Jeśli jednak polegać na podzbiór funkcjonalności nawzajem, potem chyba oddzielna klasa z własną odpowiedzialność ukryciu gdzieś tam, a następnie najlepszym rozwiązaniem byłoby wyodrębnić wspólne działanie w Trzecia klasa.W ten sposób, bardziej niż gdy klasa A opiera się na klasie B, a klasa B opiera się na klasie A, zarówno klasa A, jak i klasa B polegać będą na klasie C. Możesz bezpiecznie wykonać te wszystkie zadania, a wszystkie one pozostaną łatwe do sprawdzenia.

Jak łatwo określić, co powinna zawierać nowa klasa C? Wielka zasada pochodzi od http://misko.hevery.com/2008/08/01/circular-dependency-in-constructors-and-dependency-injection/ ... "Lista wszystkich metod w klasie A używanych przez klasę B i wszystkie metody w klasie B używane przez klasę A. Im krótsza z dwóch list jest ukryta klasa C . "

Powiązane problemy