Puncte:1

Injectarea unei noi instanțe a unui serviciu într-o altă clasă de servicii

drapel de

Am un serviciu (pentru trimiterea alertelor de eroare) care este utilizat de mai multe alte servicii.

Serviciul de alertă este injectat în acele clase prin fișierele relevante services.yml și prin constructorii acestora.

Cu toate acestea, ambele clase au aceeași instanță a serviciului (ceva de care de fapt nu mi-am dat seama până acum). Dacă am setat o proprietate dintr-o clasă, este disponibilă pentru cealaltă clasă pentru a o utiliza mai târziu.

În unele cazuri, acest lucru va fi grozav, dar în cazul meu de utilizare vreau ca fiecare clasă să înceapă cu o nouă instantare a clasei de serviciu de alertă.

Există o modalitate, prin services.yml, constructorii sau prin alte mijloace, de a realiza acest lucru?

Jaypan avatar
drapel de
Serviciile sunt prin design unice - sunt menite să fie instanțiate o singură dată. Serviciile oferă funcționalitate, nu sunt neapărat menite pentru stocarea datelor, așa că probabil că trebuie să regândiți arhitectura din spatele modului în care stocați datele și să le stocați în raport cu un obiect sau în clasa care apelează serviciul.
Geat avatar
drapel de
Are sens. Există un echivalent non-singleton al unui serviciu care poate fi injectat într-o clasă?
Jaypan avatar
drapel de
Nu, dar dacă nu a fost un singleton, nu ar trebui să fie injectat, puteți doar să instanțiați o nouă instanță a clasei dvs. după cum este necesar.
Geat avatar
drapel de
Prefer ideea de a folosi un serviciu din fabrică, în special pentru clasele care au o mulțime de argumente de constructor.
4uk4 avatar
drapel cn
În Drupal, serviciile sunt implicit singleton-uri (partajate). Dar puteți defini un serviciu nepartajat. Consultați https://symfony.com/doc/current/service_container/shared.html
Geat avatar
drapel de
@4k4 Am impresia că nu așa intenționează Drupal să fie folosite serviciile, dar este exact ceea ce căutam.
Puncte:3
drapel cn

Răspunsul direct este citarea documentației Symfony:

În containerul de servicii, toate serviciile sunt partajate implicit. Acest înseamnă că de fiecare dată când recuperați serviciul, veți primi același lucru instanță. Acesta este de obicei comportamentul pe care îl doriți, dar în unele cazuri, poate doriți să obțineți întotdeauna o instanță nouă.

Pentru a obține întotdeauna o instanță nouă, setați setarea partajată la false în definiția serviciului dvs.:

# config/services.yaml
Servicii:
    App\SomeNonSharedService:
        împărtășit: fals
        #...

https://symfony.com/doc/current/service_container/shared.html

Discutarea intențiilor Drupal este dificil pentru că nu există multe referințe. Când a fost proiectat Drupal 8, această setare de serviciu nu exista și predecesorul era deja contestat din cauza domeniului de aplicare a cererii acum eliminat. Nu am găsit nicio referință că Drupal este părtinitor împotriva utilizării serviciilor nepartajate. Dimpotrivă, aici o discuție în care core a trecut în cele din urmă de la o fabrică la un serviciu non-shared, care de fapt este și o soluție bazată pe fabrică, doar că aceasta este o fabrică deja implementată în Symfony:

https://www.drupal.org/project/drupal/issues/2660124#comment-12318542

Puncte:2
drapel ph

Există câteva opțiuni care îmi vin în minte:

  1. Creați un serviciu din fabrică care oferă instanțe ale clasei dvs. de alerte care nu sunt legate de serviciu
  2. Implementați clasa dvs. de alertă ca plugin

Pe care o alegeți depinde cu adevărat de arhitectura dvs.

Geat avatar
drapel de
Am refactorizat codul, iar service-ul din fabrică funcționează frumos.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.