Hoe Laravel-serviceproviders te registreren en te gebruiken

Als u het Laravel-raamwerk ooit bent tegengekomen, is het hoogst onwaarschijnlijk dat u nog nooit hebt gehoord van servicecontainers en serviceproviders. Sterker nog, ze vormen de ruggengraat van het Laravel-raamwerk en doen al het zware werk als je een exemplaar van een Laravel-toepassing start.

In dit artikel gaan we een glimp opvangen van wat de servicecontainer inhoudt, en daarna bespreken we de serviceprovider in detail. In de loop van dit artikel zal ik ook laten zien hoe je een aangepaste serviceprovider in Laravel kunt maken. Nadat u een serviceprovider hebt gemaakt, moet u deze ook registreren bij de Laravel-app om deze daadwerkelijk te gebruiken, dus we zullen ook die doornemen.

Er zijn twee belangrijke methoden, opstarten en registreren, die uw serviceprovider mogelijk implementeert, en in het laatste deel van dit artikel zullen we deze twee methoden grondig bespreken.

Voordat we ingaan op de bespreking van een serviceprovider, zal ik proberen de servicecontainer te introduceren omdat deze zwaar zal worden gebruikt bij de implementatie van uw serviceprovider.

Informatie over servicecontainers en serviceproviders

Wat is een servicecontainer?

In de eenvoudigste bewoordingen zouden we kunnen zeggen dat de servicecontainer in Laravel een vak is dat de bindingen van verschillende componenten bevat, en ze worden waar nodig geserveerd in de hele applicatie.

In de woorden van de officiële documentatie van Laravel:

De Laravel-servicecontainer is een krachtig hulpmiddel voor het beheren van klassenafhankelijkheden en het uitvoeren van afhankelijkheidsinjectie.

Dus wanneer u een ingebouwd component of een ingebouwde service wilt injecteren, kunt u dit typen in uw constructor of methode, en het wordt automatisch ingespoten vanuit de servicecontainer omdat het alles bevat wat u nodig heeft! Is dat niet cool? U hoeft de componenten niet handmatig te instantiëren en vermijdt zo een strakke koppeling in uw code.

Laten we een snel voorbeeld bekijken om het te begrijpen.

Class SomeClass public function __construct (FooBar $ foobarObject) // use $ foobarObject object

Zoals u kunt zien, de SomeClass heeft een instantie nodig van FooBar zichzelf te instantiëren. In feite heeft het dus een afhankelijkheid die moet worden geïnjecteerd. Laravel doet dit automatisch door in de servicecontainer te kijken en de juiste afhankelijkheid te injecteren.

En als u zich afvraagt ​​hoe Laravel weet welke componenten of services in de servicecontainer moeten worden opgenomen, is het antwoord de serviceprovider. Het is de serviceprovider die Laravel opdraagt ​​om verschillende componenten in de servicecontainer te binden. In feite worden dit service containerverbindingen genoemd en u moet dit doen via de serviceprovider.

Het is dus de serviceprovider die alle bindingen van de servicecontainer registreert, en dit gebeurt via de registratiemethode van de implementatie van de serviceprovider.

Dat zou een andere vraag op tafel moeten leggen: hoe weet Laravel over verschillende dienstverleners? Heb je net iets gezegd? Ik heb zojuist iemand dat horen zeggen, Laravel moet dat ook automatisch uitvogelen! Oh jongen, dat is te veel om te vragen: Laravel is een raamwerk, geen superman, toch? Een grapje, dat is iets dat je Laravel expliciet moet laten weten.

Ga je gang en bekijk de inhoud van de config / app.php het dossier. U vindt een array-invoer die alle serviceproviders weergeeft die worden geladen tijdens het bootstrappen van de Laravel-toepassing.

'providers' => [/ * * Laravel Framework Service Providers ... * / Illuminate \ Auth \ AuthServiceProvider :: class, Illuminate \ Broadcasting \ BroadcastServiceProvider :: class, Illuminate \ Bus \ BusServiceProvider :: class, Illuminate \ Cache \ CacheServiceProvider :: class, Illuminate \ Foundation \ Providers \ ConsoleSupportServiceProvider :: class, Illuminate \ Cookie \ CookieServiceProvider :: class, Illuminate \ Database \ DatabaseServiceProvider :: class, Illuminate \ Encryption \ EncryptionServiceProvider :: class, Illuminate \ Filesystem \ FilesystemServiceProvider :: class, Illuminate \ Foundation \ Providers \ FoundationServiceProvider :: class, Illuminate \ Hashing \ HashServiceProvider :: class, Illuminate \ Mail \ MailServiceProvider :: class, Illuminate \ Notifications \ NotificationServiceProvider :: class, Illuminate \ Pagination \ PaginationServiceProvider :: class, Illuminate \ Pipeline \ PipelineServiceProvider :: class, Illuminate \ Queue \ QueueServiceProvider :: class, Illuminate \ Redis \ RedisServiceProvider :: class, Illuminate \ Auth \ Passwords \ PasswordResetServiceP rovider :: class, Illuminate \ Session \ SessionServiceProvider :: class, Illuminate \ Translation \ TranslationServiceProvider :: class, Illuminate \ Validation \ ValidationServiceProvider :: class, Illuminate \ View \ ViewServiceProvider :: class, / * * Pakketproviders ... * / Laravel \ Tinker \ TinkerServiceProvider :: class, / * * Application Service Providers ... * / App \ Providers \ AppServiceProvider :: class, App \ Providers \ AuthServiceProvider :: class, // App \ Providers \ BroadcastServiceProvider :: class, App \ Providers \ EventServiceProvider :: class, App \ Providers \ RouteServiceProvider :: class,],

Dus dat was de servicecontainer tot uw beschikking. Vanaf het volgende gedeelte zullen we ons concentreren op de serviceprovider, wat het hoofdonderwerp van dit artikel is!

Wat is een serviceprovider?

Als de servicecontainer iets is waarmee u bindingen kunt definiëren en afhankelijkheden kunt injecteren, is de serviceprovider de plaats waar deze plaatsvindt.

Laten we even kijken naar een van de belangrijkste serviceproviders om te begrijpen wat het doet. Ga je gang en open de vender / laravel / framework / src / Illuminate / Cache / CacheServiceProvider.php het dossier.

public function register () $ this-> app-> singleton ('cache', function ($ app) retourneer nieuwe CacheManager ($ app);); $ this-> app-> singleton ('cache.store', function ($ app) return $ app ['cache'] -> driver ();); $ this-> app-> singleton ('memcached.connector', function () retourneer nieuwe MemcachedConnector;); 

Het belangrijkste om op te merken is de registreren methode, waarmee u servicecontainerbindingen kunt definiëren. Zoals u kunt zien, zijn er drie bindingen voor de cache, cache.store en memcached.connector Diensten.

Kortom, we informeren Laravel dat er altijd een probleem moet worden opgelost cache invoer, moet het exemplaar van CacheManager. Dus we voegen gewoon een soort van toewijzing toe in de servicecontainer waartoe toegang kan worden verkregen $ This-> app.

Dit is de juiste manier om een ​​service aan een Laravel-servicecontainer toe te voegen. Dat stelt u ook in staat om het grotere beeld te realiseren van hoe Laravel de registratiemethode van alle serviceproviders doorloopt en de servicecontainer vult! En zoals we eerder hebben vermeld, haalt het de lijst met serviceproviders op uit de config / app.php het dossier.

En dat is het verhaal van de serviceprovider. In het volgende gedeelte bespreken we hoe u een aangepaste serviceprovider kunt maken, zodat u uw aangepaste services kunt registreren in de Laravel-servicecontainer.

Maak uw aangepaste serviceprovider

Laravel wordt al geleverd met een praktische opdrachtregelhulpprogramma, ambachtsman, waarmee u de sjablooncode kunt maken, zodat u deze niet helemaal opnieuw hoeft te maken. Ga door en ga naar de opdrachtregel en voer de volgende opdracht uit in de hoofdmap van uw toepassing om een ​​aangepaste serviceprovider te maken.

$ php artisan make: provider EnvatoCustomServiceProvider Provider is succesvol gemaakt.

En dat zou het bestand moeten maken EnvatoCustomServiceProvider.php onder de app / Providers directory. Open het bestand om te zien wat het bevat.

Zoals we eerder hebben besproken, zijn er twee methoden, opstarten en registreren, waarmee u het grootste deel van de tijd te maken krijgt wanneer u met uw aangepaste serviceprovider werkt.

De registreren methode is de plaats waar u al uw aangepaste service containerverbindingen definieert. Aan de andere kant, de bagageruimte methode is de plaats waar u al geregistreerde diensten kunt gebruiken via de registratiemethode. In het laatste deel van dit artikel zullen we deze twee methoden in detail bespreken, aangezien we enkele praktische use-cases zullen doornemen om het gebruik van beide methoden te begrijpen.

Registreer uw Custom Service Provider

Dus je hebt je aangepaste serviceprovider gemaakt. Dat is geweldig! Vervolgens moet u Laravel informeren over uw aangepaste serviceprovider zodat deze deze tijdens het bootstrapping samen met andere serviceproviders kan laden.

Om uw serviceprovider te registreren, hoeft u alleen maar een vermelding toe te voegen aan de reeks serviceproviders in de config / app.php het dossier.

'providers' => [/ * * Laravel Framework Service Providers ... * / Illuminate \ Auth \ AuthServiceProvider :: class, Illuminate \ Broadcasting \ BroadcastServiceProvider :: class, Illuminate \ Bus \ BusServiceProvider :: class, Illuminate \ Cache \ CacheServiceProvider :: class, Illuminate \ Foundation \ Providers \ ConsoleSupportServiceProvider :: class, Illuminate \ Cookie \ CookieServiceProvider :: class, Illuminate \ Database \ DatabaseServiceProvider :: class, Illuminate \ Encryption \ EncryptionServiceProvider :: class, Illuminate \ Filesystem \ FilesystemServiceProvider :: class, Illuminate \ Foundation \ Providers \ FoundationServiceProvider :: class, Illuminate \ Hashing \ HashServiceProvider :: class, Illuminate \ Mail \ MailServiceProvider :: class, Illuminate \ Notifications \ NotificationServiceProvider :: class, Illuminate \ Pagination \ PaginationServiceProvider :: class, Illuminate \ Pipeline \ PipelineServiceProvider :: class, Illuminate \ Queue \ QueueServiceProvider :: class, Illuminate \ Redis \ RedisServiceProvider :: class, Illuminate \ Auth \ Passwords \ PasswordResetServiceP rovider :: class, Illuminate \ Session \ SessionServiceProvider :: class, Illuminate \ Translation \ TranslationServiceProvider :: class, Illuminate \ Validation \ ValidationServiceProvider :: class, Illuminate \ View \ ViewServiceProvider :: class, / * * Pakketproviders ... * / Laravel \ Tinker \ TinkerServiceProvider :: class, / * * Application Service Providers ... * / App \ Providers \ AppServiceProvider :: class, App \ Providers \ AuthServiceProvider :: class, // App \ Providers \ BroadcastServiceProvider :: class, App \ Providers \ EventServiceProvider :: class, App \ Providers \ RouteServiceProvider :: class, App \ Providers \ EnvatoCustomServiceProvider :: class,],

En dat is het! U hebt uw dienstverlener geregistreerd bij het Laravel-stelsel van dingen! Maar de serviceprovider die we hebben gemaakt, is bijna een lege sjabloon en heeft op dit moment geen zin. In het volgende gedeelte zullen we een aantal praktische voorbeelden doornemen om te zien wat u kunt doen met de register- en opstartmethoden.

Ga door het register en de opstartmethoden

Om te beginnen, gaan we door de registreren methode om te begrijpen hoe je het echt zou kunnen gebruiken. Open het serviceproviderbestand app / Providers / EnvatoCustomServiceProvider.php die eerder is gemaakt en vervang de bestaande code door het volgende.

app-> bind ('App \ Bibliotheek \ Services \ DemoOne', functie ($ app) return new DemoOne ();); 

Er zijn twee belangrijke zaken om op te merken:

  • We hebben geïmporteerd App \ Library \ Services \ DemoOne zodat we het kunnen gebruiken. De DemoOne klas is nog niet gemaakt, maar dat doen we zo meteen.
  • In de registermethode hebben we de binden methode van de servicecontainer om onze servicecontainerbinding toe te voegen. Dus, wanneer het App \ Library \ Services \ DemoOne afhankelijkheid moet worden opgelost, het zal de sluitingsfunctie aanroepen, en het instantiseert en retourneert het App \ Library \ Services \ DemoOne voorwerp.

Dus je hoeft alleen maar het te maken app / Library / Services / DemoOne.php bestand om dit te laten werken.

En hier is de code ergens in uw controller waar de afhankelijkheid zal worden geïnjecteerd.

doSomethingUseful (); 

Dat is een heel eenvoudig voorbeeld van het binden van een klas. In het bovenstaande voorbeeld is het eigenlijk niet nodig om een ​​serviceprovider te maken en de registratiemethode te implementeren zoals we deden, aangezien Laravel het automatisch kan oplossen met behulp van reflectie.

Een zeer belangrijke opmerking uit de documentatie van Laravel:

Het is niet nodig om klassen in de container te binden als ze niet afhankelijk zijn van interfaces. De container hoeft niet te worden geïnstrueerd over het bouwen van deze objecten, omdat deze deze objecten automatisch kan oplossen met behulp van reflectie.

Aan de andere kant zou het erg handig zijn geweest als je een interface had gekoppeld aan een bepaalde implementatie. Laten we een voorbeeld doornemen om het te begrijpen.

Laten we een heel eenvoudige interface maken op app / Library / Services / Contracten / CustomServiceInterface.php.

Laten we vervolgens twee concrete implementaties van deze interface maken. Kortom, we hoeven alleen maar twee klassen te maken die het CustomServiceInterface interface.

Maak het DemoOne klasse in app / Library / Services / DemoOne.php.

evenzo, DemoTwo gaat erin app / Library / Services / DemoTwo.php.

In plaats van een klas te binden, binden we nu een interface. opnieuw bezoeken EnvatoCustomServiceProvider.php en verander de code zoals hieronder getoond.

app-> bind ('App \ Bibliotheek \ Services \ Contracts \ CustomServiceInterface', functie ($ app) return new DemoOne ();); 

In dit geval hebben we de App \ Library \ Services \ contracten \ CustomServiceInterface interface met de DemoOne implementatie. Vandaar, wanneer de App \ Library \ Services \ contracten \ CustomServiceInterface afhankelijkheid moet worden opgelost, het maakt een instantiatie en retourneert het App \ Library \ Services \ DemoOne voorwerp. Nu is het logischer, nietwaar?

Laten we ook de controllercode snel herzien.

doSomethingUseful (); 

Zoals je misschien al geraden had, de $ customServiceInstance zou het voorbeeld moeten zijn van App \ Library \ Services \ DemoOne! Het mooie van deze aanpak is dat je de DemoOne implementatie met de andere gemakkelijk.

Laten we zeggen dat je de. Wilt gebruiken DemoTwo implementatie in plaats van DemoOne. In dat geval hoeft u alleen maar de volgende wijzigingen in de serviceprovider aan te brengen EnvatoCustomServiceProvider.php.

Zoek de volgende regel:

gebruik App \ Library \ Services \ DemoOne;

En vervang het door:

gebruik App \ Library \ Services \ DemoTwo;

Zoek ook deze:

return nieuwe DemoOne ();

Dat zou moeten worden vervangen door:

return nieuwe DemoTwo ();

Dezelfde aanpak kan worden gebruikt als u elke kernimplementatie wilt vervangen door die van uzelf. En het is niet alleen de bindmethode die u zou kunnen gebruiken voor uw service containerverbindingen; de Laravel-servicecontainer biedt verschillende manieren om in de servicecontainer te binden. Raadpleeg de officiële Laravel-documentatie voor de volledige referentie.

De volgende kandidaat is de bagageruimte methode, die u zou kunnen gebruiken om de kern Laravel-functionaliteit uit te breiden. In deze methode hebt u toegang tot alle services die zijn geregistreerd met behulp van de registratiemethode van de serviceprovider. In de meeste gevallen wilt u uw evenementlisteners registreren op deze methode, die wordt geactiveerd wanneer er iets gebeurt.

Laten we een paar voorbeelden bekijken die de implementatie van de opstartmethode vereisen.

U wilt uw eigen formulierveldvalidator toevoegen aan Laravel.

openbare functie boot () Validator :: extend ('my_custom_validator', function ($ attribute, $ value, $ parameters, $ validator) // validatielogica gaat hier ...); 

Als u een view-componist wilt registreren, is dit de perfecte plek om dat te doen! In feite zouden we kunnen zeggen dat de opstartmethode vaak wordt gebruikt om view-componisten toe te voegen!

public function boot () View :: composer ('demo', 'App \ Http \ ViewComposers \ DemoComposer'); 

Natuurlijk wilt u een gevel importeren Verlichten \ Support \ Gevels \ View in de eerste plaats bij uw serviceprovider.

In hetzelfde gebied kunt u de gegevens ook delen in meerdere weergaven!

openbare functie boot () View: share ('key', 'value'); 

Het kan ook worden gebruikt om expliciete modelbindingen te definiëren.

openbare functie boot () parent :: boot (); Route :: model ('gebruiker', App \ Gebruiker :: klasse); 

Dit waren een paar voorbeelden om het gebruik van de opstartmethode te demonstreren. Hoe meer je in Laravel komt, hoe meer redenen je zult vinden om het te implementeren!

En daarmee zijn we aan het einde van dit artikel gekomen. Ik hoop dat je genoten hebt van de onderwerpen die in dit artikel zijn besproken.

Conclusie

Het was de discussie over dienstverleners die de belangrijkste attractie van dit artikel was, hoewel we ons artikel met de servicecontainer begonnen omdat dat een belangrijk ingrediënt was om de dienstverlener te begrijpen.

Daarna hebben we een service provider op maat ontwikkeld en in de tweede helft van het artikel hebben we een aantal praktische voorbeelden besproken.

Voor degenen onder u die net zijn begonnen met Laravel of die uw kennis, site of applicatie willen uitbreiden met uitbreidingen, hebben we een aantal dingen die u kunt bestuderen bij Envato Market.

Als je vragen of opmerkingen hebt, kun je deze gewoon schieten met de onderstaande feed!