44
55namespace DI \Definition ;
66
7+ use DI \Definition \Exception \InvalidDefinition ;
8+ use DI \ServiceLocator ;
79use Psr \Container \ContainerInterface ;
810
911/**
1315 */
1416class Reference implements Definition, SelfResolvingDefinition
1517{
18+ public static $ serviceLocatorClass = ServiceLocator::class;
19+
1620 /** Entry name. */
1721 private string $ name = '' ;
1822
19- /**
20- * @param string $targetEntryName Name of the target entry
21- */
23+ private bool $ isServiceLocatorEntry ;
24+
2225 public function __construct (
26+ /**
27+ * @var string Name of the target entry
28+ */
2329 private string $ targetEntryName ,
30+ /**
31+ * @var string|null name of an entry - holder of a definition requesting this entry
32+ */
33+ private ?string $ requestingName = null ,
34+ private ?ServiceLocatorDefinition $ serviceLocatorDefinition = null
2435 ) {
36+ $ this ->isServiceLocatorEntry = $ targetEntryName === self ::$ serviceLocatorClass ;
2537 }
2638
2739 public function getName () : string
@@ -39,13 +51,50 @@ public function getTargetEntryName() : string
3951 return $ this ->targetEntryName ;
4052 }
4153
54+ /**
55+ * Returns the name of the entity requesting this entry.
56+ */
57+ public function getRequestingName () : string
58+ {
59+ return $ this ->requestingName ;
60+ }
61+
62+ public function isServiceLocatorEntry () : bool
63+ {
64+ return $ this ->isServiceLocatorEntry ;
65+ }
66+
67+ public function getServiceLocatorDefinition () : ServiceLocatorDefinition
68+ {
69+ if (!$ this ->isServiceLocatorEntry || $ this ->requestingName === null ) {
70+ throw new InvalidDefinition (sprintf (
71+ "Invalid service locator definition ('%s' for '%s') " ,
72+ $ this ->targetEntryName ,
73+ $ this ->requestingName
74+ ));
75+ }
76+ if (!$ this ->serviceLocatorDefinition ) {
77+ $ this ->serviceLocatorDefinition = new ServiceLocatorDefinition ($ this ->getTargetEntryName (), $ this ->requestingName );
78+ }
79+
80+ return $ this ->serviceLocatorDefinition ;
81+ }
82+
4283 public function resolve (ContainerInterface $ container ) : mixed
4384 {
85+ if ($ this ->isServiceLocatorEntry ) {
86+ return $ this ->getServiceLocatorDefinition ()->resolve ($ container );
87+ }
88+
4489 return $ container ->get ($ this ->getTargetEntryName ());
4590 }
4691
4792 public function isResolvable (ContainerInterface $ container ) : bool
4893 {
94+ if ($ this ->isServiceLocatorEntry ) {
95+ return $ this ->getServiceLocatorDefinition ()->isResolvable ($ container );
96+ }
97+
4998 return $ container ->has ($ this ->getTargetEntryName ());
5099 }
51100
0 commit comments