Devloger

Laravel Service Container (IoC) - Co to jest?

Laravel Service Container (IoC) – Co to jest?

Logotyp Laravela

To jest pytanie które pada nawet częściej od tego związnego z Middleware. Jest to bardzo prosta rzecz choć brzmi skomplikowanie a dokumentacja Laravela w zrozumieniu niestety nie pomaga.

I cóż począć? A no wiadomo co, przeczytać ten artykuł Emotikon uśmiechniętej buźki! Ponieważ wyłożę ci wszystko jak należy Emotikon uśmiechniętej buźki!

Zatem czym jest Service Container?

Service Container (inaczej IoC Container) jest to nic innego jak narzędzie do zarządzania zależnościami między klasami oraz do wstrzykiwania zależności. Brzmi skomplikowani, prawda? Ale takie nie jest Emotikon uśmiechniętej buźki. Bo czymże jest w ogóle to „wstrzykiwanie zależności”?

Zrozumienie dobrze tego zagadnienia jest kluczowe w budowaniu potężnych, dużych i skalowalnych aplikacji w Laravelu Emotikon uśmiechniętej buźki.

Dependency Injection (Wstrzykiwanie zależności)

Ano jest to po prostu dostarczanie klasom tego czego potrzebują do prawidłowego funkcjonowania. Zazwyczaj są to inne klasy które zwykle się „wstrzykuje” przez konstruktor bądź tzw. setter. Jest to innymi słowy przekazywanie argumentów. Po prostu Emotikon uśmiechniętej buźki.

Świeże spojrzenie

Możesz myśleć o tym, jak o takim szczególnym miejscu, gdzie możesz zdefiniować całą kompozycję jakiejś konkretnej klasy – jak należy ją zbudować według twojej wizji, jak chcesz by została zbudowana. Dzięki temu nie musisz pamiętać w jaki sposób należy stworzyć instancje jakiejś konkretnej klasy za każdym jednym razem. Zamiast tego możesz napisać to tylko raz w jednym konkretnym miejscu, a potem w przyszłości kiedy zajdzie potrzeba dostępu do tego obiektu, będziesz mógł po prostu go wywołać z kontenera IoC Emotikon uśmiechniętej buźki. W związku z tym rejestruje się tzw. wiązanie w kontenerze IoC.

Również możesz na to patrzeć jak na zwykły kontener/pudełko gdzie przechowujemy wszystkie powiązania w naszej aplikacji (bindings).

Automatic Resolution

A to dopiero początek, ponieważ Laravel dostarczy ci na własną rękę potrzebne zależności, dokładnie tam gdzie ich potrzebujesz Emotikon uśmiechniętej buźki. Wyobraź sobie klasę A która do działania potrzebuje klasę B. Przyjmujesz ją jako argument poprzez konstruktor tejże klasy A. Wówczas musisz utworzyć klasę A poprzez „new A(new B)”. Natomiast wykorzystując Service Container wystarczy, że zrobisz „new A” o ile wcześniej zarejestrujesz odpowiednie wiązanie między klasą A i B (kiedy zarejestrujesz sposób kompozycji klasy A która polega na klasie B w IoC).

Reflection

Co więcej, Laravel jest nawet na tyle sprytny, że znając twoje type-hinty z konstruktora (zależności) pomimo tego że nie są one zarejestrowane w kontenerze IoC, w sposób automatyczny wstrzyknie to co niezbędne używając mechanizmu pod nazwą „Reflection” poprzez „Automatic Resolution” Emotikon uśmiechniętej buźki. Automatycznie stworzy niezbędne instancje danych klas. I jakby tego było mało, działa to w pełni rekursywnie, dostarczy ci wszystkie potrzebne zależności i zależności tych zależności itd… Cudowna technika Emotikon uśmiechniętej buźki.

Co to jest Reflection?

Co do reflection słów kilka; Jest to API które pozwala na dokonanie inżynierii wstecznej na klasach, interfejsach, funkcjach, metodach bądź bibliotekach.

Czy można tylko i wyłącznie rejestrować klasy w kontenerze IoC?

Nie Emotikon uśmiechniętej buźki. Niemalże wszystko możesz tam zarejestrować oraz stamtąd wyciągnąć Emotikon uśmiechniętej buźki. Więc jest to niesamowicie przydatne narzędzie które jest kluczowym elementem tego frameworka Emotikon uśmiechniętej buźki.

Podstawowe wiązanie

Prawie wszystkich wiązań dokonujemy w specjalnie do tego przeznaczonych klasach – Service Providers. Podstawowe wiązanie tworzymy bind-ując  dany identyfikator (zazwyczaj nazwę klasy czy interfejsu) do konkretnego sposobu jej kompozycji czy nawet innej klasy.

$this->app->bind('HelpSpot\API', function ($app) {
    return new HelpSpot\API($app->make('HttpClient'));
});

Pojedyncze wiązanie – Singleton

Jest to wiązanie w wyniku którego za każdym razem gdy zwrócimy się do kontenera IoC z żądaniem o konkretną klasę, to zawsze dostaniemy jedną i tę samą jej instancję. Zostanie utworzona tylko raz i nigdy nie dostaniemy innej lub nowej instancji tejże klasy Emotikon uśmiechniętej buźki. Jest to bardzo przydatna możliwość którą można wykorzystać na bardzo wiele sposobów.

$this->app->singleton('HelpSpot\API', function ($app) {
    return new HelpSpot\API($app->make('HttpClient'));
});

Wiązanie konkretnych instancji

$api = new HelpSpot\API(new HttpClient);

$this->app->instance('HelpSpot\API', $api);

Masz również możliwość z-bind-ować konkretną instancję do kontenera IoC, w związku z czym za każdym razem zostanie zwrócona właśnie ta konkretna instancja.

Wiązanie typów podstawowych

Równie przydatną możliwością jaką masz, jest powiązanie jakiejś wartości z zakresu podstawowych typów danych (np. integer) do konkretnej klasy pod konkretnym identyfikatorem zmiennej Emotikon uśmiechniętej buźki. Wówczas żądanie o wspomnianą zmienną zwróci tę właśnie wcześniej powiązaną przez ciebie konkretną wartość.

$this->app->when('App\Http\Controllers\UserController')
          ->needs('$variableName')
          ->give($value);

Wiązanie interfejsu do implementacji

Jeśli potrzebujesz powiązać interfejs z konkretną jego implementacją, też masz taką możliwość. Gdy będziesz potrzebował instancji tego interfejsu to zwrócony zostanie obiekt klasy który sam wcześniej powiązałeś z tym interfejsem w kontenerze IoC Emotikon uśmiechniętej buźki.

$this->app->bind(
    'App\Contracts\EventPusher',
    'App\Services\RedisEventPusher'
);

Wiązanie interfejsu w zależności od kontekstu

Co więcej, gdy potrzebujesz powiązać dwie ale wyciągnąć jedną implementacje danego interfejsu - w zależności od klasy która domaga się jego instancji – też masz taką możliwość Emotikon uśmiechniętej buźki!

$this->app->when(PhotoController::class)
          ->needs(Filesystem::class)
          ->give(function () {
              return Storage::disk('local');
          });

Wyciąganie

Są trzy sposoby wyciągania z kontenera IoC. Możesz to zrobić wykorzystując wstrzyknięcie poprzez konstruktor, wykorzystując wstrzyknięcie poprzez sygnaturę metody/funkcji lub po prostu wyciągnąć z użyciem specjalnie do tego przeznaczonych funkcji pomocniczych, takich jak „resolve()”.

$api = resolve('HelpSpot\API');

Jeżeli danej klasy nie wyciągasz z wykorzystaniem kontenera IoC, możesz to zrobić z wykorzystaniem tablicy asocjacyjnej do metody „makeWith”.

$api = $this->app->makeWith('HelpSpot\API', ['id' => 1]);

Tagowanie

Masz również możliwość łączenia konkretnych wiązań w tagi/kategorie. Wówczas masz możliwość wyciągnąć je wszystkie na raz posługując się zdefiniowanym tagiem Emotikon uśmiechniętej buźki.

$this->app->bind('SpeedReport', function () {
    //
});

$this->app->bind('MemoryReport', function () {
    //
});

$this->app->tag(['SpeedReport', 'MemoryReport'], 'reports');

Wydarzenia kontenera IoC

Warto wspomnieć, że za każdym razem gdy Service Container wyciąga jakikolwiek obiekt, to wyrzuca event którego powstanie możesz nasłuchiwać Emotikon uśmiechniętej buźki. Możesz w ten sposób przechwycić obiekt zanim zostanie przesłany na żądanie i dokonać jego modyfikacji w locie Emotikon uśmiechniętej buźki.

$this->app->resolving(function ($object, $app) {
    // Called when container resolves object of any type...
});

$this->app->resolving(HelpSpot\API::class, function ($api, $app) {
    // Called when container resolves objects of type "HelpSpot\API"...
});

PSR-11

Laravelowy kontener IoC implementuje interfejs PSR-11. W związku z czym możesz wprowadzić „ContainerInterface” jako type-hint by uzyskać instancję całego kontenera IoC Emotikon uśmiechniętej buźki. Następnie możesz wyciągnąć z niego jakikolwiek serwis tylko potrzebujesz. Lub dokonać jakiejkolwiek innej akcji na nim.

Route::get('/', function (ContainerInterface $container) {
    $service = $container->get('Service');

I to już wszystko w temacie Service Container-a

Wyłożone jak należy Emotikon uśmiechniętej buźki. Dziękuję za lekturę i zapraszam do czytania innych moich artykułów Emotikon uśmiechniętej buźki.

Jeśli nurtuje cię kwestia Middleware w Laravelu - zapraszam do tego artykułu Emotikon uśmiechniętej buźki!

Zapraszam również do tematu poświęconego ochronie przeciw CSRF Emotikon uśmiechniętej buźki.

Bywaj!

Krystian Bogucki

Podobał Ci się ten artykuł?

Jeśli tak, to zarejestruj się aby otrzymywać powiadomienia o nowych artykułach. Nie ujawnię nikomu Twojego adresu!