Hur registrerar och använder Laravel Service Providers

Om du någonsin har stött på Laravel-ramverket är det mycket osannolikt att du inte har hört talas om servicebehållare och tjänsteleverantörer. Faktum är att de är ryggraden i Laravel-ramverket och gör allt tungt lyft när du startar en förekomst av Laravel-applikationen.

I den här artikeln kommer vi att få en glimt av vad servicebehållaren handlar om, och efter det kommer vi att diskutera tjänsteleverantören i detalj. I samband med denna artikel kommer jag också att visa hur man skapar en anpassad tjänsteleverantör i Laravel. När du har skapat en tjänsteleverantör måste du också registrera den med Laravel-ansökan för att faktiskt kunna använda den, så vi kommer också att gå igenom det.

Det finns två viktiga metoder, starta och registrera, som din tjänsteleverantör kan genomföra, och i det sista segmentet i denna artikel kommer vi att diskutera dessa två metoder noggrant.

Innan vi dyker in i diskussionen av en tjänsteleverantör, försöker jag introducera servicebehållaren eftersom den kommer att användas kraftigt i din tjänsteleverantörs implementering.

Förstå servicebehållare och serviceleverantörer

Vad är en servicebehållare?

I de enklaste termerna kan vi säga att servicebehållaren i Laravel är en låda som innehåller olika komponenters bindningar, och de serveras efter behov i hela applikationen.

Med orden i den officiella Laravel dokumentationen:

Laravel service container är ett kraftfullt verktyg för att hantera klassberoende och utföra beroendeinsprutning.

Så, när du behöver injicera någon inbyggd komponent eller tjänst, kan du skriva tips om det i din konstruktör eller metod, och det kommer att injiceras automatiskt från servicebehållaren eftersom det innehåller allt du behöver! Är det inte häftigt? Det sparar dig från att manuellt instansera komponenterna och undviker sålunda snabb koppling i din kod.

Låt oss ta en titt på ett snabbt exempel för att förstå det.

Klass SomeClass public function __construct (FooBar $ foobarObject) // använd $ foobarObject objekt

Som du kan se, är SomeClass behöver en förekomst av Foo bar att inställa sig själv. Så i grunden har det ett beroende som måste injiceras. Laravel gör det automatiskt genom att titta på servicebehållaren och injicera lämpligt beroende.

Och om du undrar hur Laravel vet vilka komponenter eller tjänster som ska inkluderas i servicebehållaren, är svaret tjänsteleverantören. Det är tjänsteleverantören som berättar Laravel att binda olika komponenter i servicebehållaren. Faktum är att det kallas service container bindningar, och du måste göra det via tjänsteleverantören.

Så det är tjänsteleverantören som registrerar alla servicebehållarens bindningar, och det görs via registermetoden för tjänsteleverantörens genomförande.

Det borde ta med en annan fråga på bordet: Hur känner Laravel om olika tjänsteleverantörer? Har du bara sagt något? Jag har just hört någon säga att Laravel ska räkna ut det automatiskt också! Åh pojke, det är för mycket att fråga: Laravel är ett ramverk, inte en superman, eller hur? Skämtar åt varandra, det är något du behöver för att informera Laravel uttryckligen.

Gå vidare och titta på innehållet i config / app.php fil. Du hittar en array-post som listar alla tjänsteleverantörer som laddas under bootstrapping av Laravel-programmet.

"leverantörer" => [/ * * Laravel Framework Service Providers ... * / Illuminate \ Auth \ AuthServiceProvider :: klass, belysa \ Broadcasting \ BroadcastServiceProvider :: klass, belysa \ Bus \ BusServiceProvider :: klass, belysa \ Cache \ CacheServiceProvider :: klass, belysa \ Foundation \ Providers \ ConsoleSupportServiceProvider :: klass, belysa \ Cookie \ CookieServiceProvider :: klass, belysa \ Databas \ DatabasServiceProvider :: klass, belysa \ Kryptering \ EncryptionServiceProvider :: klass, belysa \ Filsystem \ FilesystemServiceProvider :: klass, belysa \ Stiftelsen \ Providers \ FoundationServiceProvider :: klass, belysa \ Hashing \ HashServiceProvider :: klass, belysa \ Mail \ MailServiceProvider :: klass, belysa \ Notifieringar \ NotificationServiceProvider :: klass, belysa \ Pagination \ PaginationServiceProvider :: klass, belysa \ Pipeline \ PipelineServiceProvider :: klass, belysa \ Queue \ QueueServiceProvider :: klass, belysa \ Redis \ RedisServiceProvider :: klass, belysa \ Auth \ Lösenord \ PasswordResetServiceP rovider :: class, Illuminate \ Session \ SessionServiceProvider :: klass, belysa \ Översättning \ TranslationServiceProvider :: klass, belysa \ Validation \ ValidationServiceProvider :: klass, belysa \ View \ ViewServiceProvider :: klass, / * * Paketleverantörer ... * / Laravel \ Tinker \ TinkerServiceProvider :: klass, / * * Applikationsleverantörer ... * / App \ Providers \ AppServiceProvider :: klass, App \ Providers \ AuthServiceProvider :: klass, // App \ Providers \ BroadcastServiceProvider :: klass, App \ Providers \ EventServiceProvider :: klass, App \ Providers \ RouteServiceProvider :: klass,],

Så det var servicebehållaren till ditt förfogande. Från nästa avsnitt kommer vi att fokusera på tjänsteleverantören, vilket är huvudämnet i den här artikeln!

Vad är en tjänsteleverantör?

Om servicebehållaren är något som låter dig definiera bindningar och injicera beroenden, är tjänsteleverantören den plats där det händer.

Låt oss ta en snabb titt på en av kärnleverantörerna för att förstå vad det gör. Gå vidare och öppna vender / laravel / ram / src / Illuminate / Cache / CacheServiceProvider.php fil.

public function register () $ this-> app-> singleton ("cache", funktion ($ app) returnera nya CacheManager ($ app);); $ this-> app-> singleton ('cache.store', funktion ($ app) return $ app ['cache'] -> drivrutin ();); $ this-> app-> singleton ('memcached.connector', funktion () returnera ny MemcachedConnector;); 

Det viktiga att notera här är Registrera metod, som låter dig definiera servicebehållarens bindningar. Som ni kan se finns det tre bindningar för cache, cache.store och memcached.connector tjänster.

I grund och botten informerar vi Laravel om det finns ett behov av att lösa ett cache inträde, det borde returnera förekomsten av CacheManager. Så vi lägger bara till en slags kartläggning i servicebehållaren som kan nås via $ This-> app.

Det här är rätt sätt att lägga till någon tjänst i en Laravel service container. Det gör det också möjligt för dig att inse den större bilden av hur Laravel går igenom registreringsmetoden för alla tjänsteleverantörer och fyller tjänstebehållaren! Och som vi tidigare nämnt tar det upp listan över tjänsteleverantörer från config / app.php fil.

Och det är tjänsteleverantörens berättelse. I nästa avsnitt diskuterar vi hur du skapar en anpassad tjänsteleverantör så att du kan registrera dina anpassade tjänster i Laravel servicebehållaren.

Skapa din anpassade tjänsteleverantör

Laravel levereras redan med ett hands-on kommandoradsverktyg, hantverkare, som låter dig skapa mallkod så att du inte behöver skapa den från början. Gå vidare och flytta till kommandoraden och kör följande kommando i din applikationsrot för att skapa en anpassad tjänsteleverantör.

$ php artisan make: leverantör EnvatoCustomServiceProvider Provider skapades framgångsrikt.

Och det borde skapa filen EnvatoCustomServiceProvider.php under app / leverantörer katalogen. Öppna filen för att se vad den innehåller.

Som vi diskuterade tidigare finns det två metoder, starta och registrera, att du kommer att hantera det mesta då du jobbar med din egen tjänsteleverantör.

De Registrera Metod är den plats där du definierar alla dina anpassade servicebehållarbindningar. Å andra sidan, känga Metod är den plats där du kan konsumera redan registrerade tjänster via registreringsmetoden. I det sista segmentet i denna artikel kommer vi att diskutera dessa två metoder i detalj, eftersom vi ska gå igenom några praktiska användarfall för att förstå användningen av båda metoderna.

Registrera din kundanpassade tjänsteleverantör

Så du har skapat din anpassade tjänsteleverantör. Toppen! Därefter måste du informera Laravel om din anpassade tjänsteleverantör så att den kan ladda den tillsammans med andra tjänsteleverantörer under bootstrapping.

För att registrera din tjänsteleverantör behöver du bara lägga till en post i utbudet av tjänsteleverantörer i config / app.php fil.

"leverantörer" => [/ * * Laravel Framework Service Providers ... * / Illuminate \ Auth \ AuthServiceProvider :: klass, belysa \ Broadcasting \ BroadcastServiceProvider :: klass, belysa \ Bus \ BusServiceProvider :: klass, belysa \ Cache \ CacheServiceProvider :: klass, belysa \ Foundation \ Providers \ ConsoleSupportServiceProvider :: klass, belysa \ Cookie \ CookieServiceProvider :: klass, belysa \ Databas \ DatabasServiceProvider :: klass, belysa \ Kryptering \ EncryptionServiceProvider :: klass, belysa \ Filsystem \ FilesystemServiceProvider :: klass, belysa \ Stiftelsen \ Providers \ FoundationServiceProvider :: klass, belysa \ Hashing \ HashServiceProvider :: klass, belysa \ Mail \ MailServiceProvider :: klass, belysa \ Notifieringar \ NotificationServiceProvider :: klass, belysa \ Pagination \ PaginationServiceProvider :: klass, belysa \ Pipeline \ PipelineServiceProvider :: klass, belysa \ Queue \ QueueServiceProvider :: klass, belysa \ Redis \ RedisServiceProvider :: klass, belysa \ Auth \ Lösenord \ PasswordResetServiceP rovider :: class, Illuminate \ Session \ SessionServiceProvider :: klass, belysa \ Översättning \ TranslationServiceProvider :: klass, belysa \ Validation \ ValidationServiceProvider :: klass, belysa \ View \ ViewServiceProvider :: klass, / * * Paketleverantörer ... * / Laravel \ Tinker \ TinkerServiceProvider :: klass, / * * Applikationsleverantörer ... * / App \ Providers \ AppServiceProvider :: klass, App \ Providers \ AuthServiceProvider :: klass, // App \ Providers \ BroadcastServiceProvider :: klass, App \ Providers \ EventServiceProvider :: klass, App \ Providers \ RouteServiceProvider :: klass, App \ Providers \ EnvatoCustomServiceProvider :: klass,],

Och det är allt! Du har registrerat din tjänsteleverantör med Laravels system av saker! Men den tjänsteleverantör som vi har skapat är nästan en tom mall och har ingen nytta för tillfället. I nästa avsnitt går vi igenom några praktiska exempel för att se vad du kan göra med registret och startmetoderna.

Gå igenom registret och startmetoderna

Till att börja med går vi igenom Registrera metod för att förstå hur du faktiskt kan använda den. Öppna tjänsteleverantörsfilen app / leverantörer / EnvatoCustomServiceProvider.php som skapades tidigare och ersätter den befintliga koden med följande.

app-> bind ('App \ Library \ Services \ DemoOne', funktion ($ app) returnera nya DemoOne ();); 

Det finns två viktiga saker att notera här:

  • Vi har importerat App \ Library \ Services \ DemoOne så att vi kan använda den. De DemoOne klassen är inte skapad ännu, men vi gör det på ett ögonblick.
  • I registret har vi använt binda Metod för servicebehållaren för att lägga till vår servicebehållare bindande. Så, när App \ Library \ Services \ DemoOne beroende måste lösas, det kommer att ringa stängningsfunktionen, och det instantiates och returnerar App \ Library \ Services \ DemoOne objekt.

Så du behöver bara skapa app / Library / tjänster / DemoOne.php filen för att detta ska fungera.

Och här är koden någonstans i din controller där beroendet kommer att injiceras.

doSomethingUseful (); 

Det är ett mycket enkelt exempel på att binda en klass. I det ovanstående exemplet behöver vi inte skapa en tjänsteleverantör och implementera registret som vi gjorde, eftersom Laravel automatiskt kan lösa det med reflektion.

En mycket viktig anteckning från Laravel dokumentation:

Det finns inget behov av att binda klasser i behållaren om de inte är beroende av några gränssnitt. Behållaren behöver inte instrueras om hur man bygger dessa objekt, eftersom det automatiskt kan lösa dessa objekt med reflektion.

Å andra sidan skulle det ha varit mycket användbart om du hade bundet ett gränssnitt till en viss implementering. Låt oss gå igenom ett exempel för att förstå det.

Låt oss skapa ett mycket enkelt gränssnitt på app / Library / tjänster / kontrakt / CustomServiceInterface.php.

Låt oss sedan skapa två konkreta implementeringar av detta gränssnitt. I grund och botten behöver vi bara skapa två klasser som sträcker sig CustomServiceInterface gränssnitt.

Skapa DemoOne klass i app / Library / tjänster / DemoOne.php.

Liknande, DemoTwo går in app / Library / tjänster / DemoTwo.php.

Nu binder vi ett gränssnitt istället för att binda en klass. Återbesök EnvatoCustomServiceProvider.php och ändra koden som visas nedan.

app-> bind ("App \ Library \ Services \ Kontrakt \ CustomServiceInterface", funktion ($ app) returnera nya DemoOne ();); 

I det här fallet har vi bundit App \ Library \ Services \ Kontrakt \ CustomServiceInterface gränssnitt till DemoOne genomförande. Därför, när App \ Library \ Services \ Kontrakt \ CustomServiceInterface beroende måste lösas, det instantiates och returnerar App \ Library \ Services \ DemoOne objekt. Nu är det mer meningsfullt, gör det inte?

Låt oss snabbt ändra kontrollkoden också.

doSomethingUseful (); 

Som du kanske har gissat, den $ customServiceInstance bör vara förekomsten av App \ Library \ Services \ DemoOne! Skönheten i detta tillvägagångssätt är att du kan byta ut DemoOne implementera med den andra enkelt.

Låt oss säga att du vill använda DemoTwo genomförande istället för DemoOne. I så fall behöver du bara göra följande ändringar i tjänsteleverantören EnvatoCustomServiceProvider.php.

Hitta följande rad:

använd App \ Library \ Services \ DemoOne;

Och ersätt det med:

använd App \ Library \ Services \ DemoTwo;

På samma sätt, hitta den här:

returnera nya DemoOne ();

Det bör ersättas med:

returnera nya DemoTwo ();

Samma tillvägagångssätt kan användas om du vill ersätta någon kärnimplementering med din egen. Och det är inte bara den bindningsmetod du kan använda för dina servicebehållarbindningar. Laravel-servicebehållaren erbjuder olika sätt att binda in servicebehållaren. Vänligen kolla in den officiella Laravel dokumentationen för den fullständiga referensen.

Nästa kandidat är känga metod som du kan använda för att förlänga kärn Laravel-funktionaliteten. Med den här metoden kan du få tillgång till alla tjänster som registrerades med hjälp av registerleverantören. I de flesta fall vill du registrera dina händelselöshoppare i denna metod, vilket kommer att utlösas när något händer.

Låt oss ta en titt på några exempel som kräver implementeringen av startmetoden.

Du vill lägga till din egen formfältvaliderare till Laravel.

public function boot () Validator :: extend ('my_custom_validator', funktion ($ attribut, $ värde, $ parametrar, $ validator) // valideringslogik går här ...); 

Skulle du vilja registrera en synkompositör är det den perfekta platsen att göra det! Faktum är att vi kan säga att startmetoden ofta används för att lägga till kompositörer!

public function boot () Visa :: kompositör ('demo', 'App \ Http \ ViewComposers \ DemoComposer'); 

Självklart vill du importera en fasad Illuminate \ Support \ Fasader \ View i din tjänsteleverantör i första hand.

På samma territorium kan du dela data över flera visningar också!

public function boot () Visa :: share ('key', 'value'); 

Det kan också användas för att definiera explicit modellbindningar.

public function boot () förälder :: boot (); Rutt :: modell ("användare", App \ Användare :: klass); 

Dessa var några exempel för att visa användningen av startmetoden. Ju mer du kommer in i Laravel, desto fler anledningar kommer du att hitta för att genomföra den!

Och med det har vi nått slutet av den här artikeln. Jag hoppas att du har haft de ämnen som diskuterades i hela denna artikel.

Slutsats

Det var diskussionen om tjänsteleverantörer som var centrumattraktionen för denna artikel, även om vi började vår artikel med servicebehållaren eftersom det var en viktig ingrediens för att förstå tjänsteleverantören.

Därefter utvecklade vi en anpassad tjänsteleverantör, och i senare delen av artikeln gick vi igenom några praktiska exempel.

För er som antingen bara börjar med Laravel eller vill utvidga din kunskap, webbplats eller ansökan med tillägg, har vi en mängd olika saker du kan studera på Envato Market.

Om du har några frågor eller kommentarer, bara skjuta den med foderet nedan!