Skip to content

Commit 76c0650

Browse files
committed
use as contextual attribute as well
1 parent 5a5982c commit 76c0650

File tree

3 files changed

+41
-8
lines changed

3 files changed

+41
-8
lines changed

src/Illuminate/Container/Attributes/Lazy.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,16 @@
33
namespace Illuminate\Container\Attributes;
44

55
use Attribute;
6+
use Illuminate\Contracts\Container\Container;
7+
use Illuminate\Contracts\Container\ContextualAttribute;
8+
use ReflectionNamedType;
9+
use ReflectionParameter;
610

7-
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_CLASS)]
8-
class Lazy
11+
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_CLASS | Attribute::TARGET_PARAMETER)]
12+
class Lazy implements ContextualAttribute
913
{
14+
public static function resolve(self $attribute, Container $container, ReflectionNamedType $type)
15+
{
16+
return proxy($type->getName(), fn () => $container->make($type->getName()));
17+
}
1018
}

src/Illuminate/Container/Container.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use ReflectionClass;
2121
use ReflectionException;
2222
use ReflectionFunction;
23+
use ReflectionNamedType;
2324
use ReflectionParameter;
2425
use TypeError;
2526

@@ -1243,8 +1244,9 @@ protected function resolveDependencies(array $dependencies)
12431244

12441245
$result = null;
12451246

1247+
//
12461248
if (! is_null($attribute = Util::getContextualAttributeFromDependency($dependency))) {
1247-
$result = $this->resolveFromAttribute($attribute);
1249+
$result = $this->resolveFromAttribute($attribute, $dependency->getType());
12481250
}
12491251

12501252
// If the class is null, it means the dependency is a string or some other
@@ -1395,7 +1397,7 @@ protected function resolveVariadicClass(ReflectionParameter $parameter)
13951397
* @param \ReflectionAttribute $attribute
13961398
* @return mixed
13971399
*/
1398-
public function resolveFromAttribute(ReflectionAttribute $attribute)
1400+
public function resolveFromAttribute(ReflectionAttribute $attribute, ?ReflectionNamedType $type = null)
13991401
{
14001402
$handler = $this->contextualAttributes[$attribute->getName()] ?? null;
14011403

@@ -1409,7 +1411,7 @@ public function resolveFromAttribute(ReflectionAttribute $attribute)
14091411
throw new BindingResolutionException("Contextual binding attribute [{$attribute->getName()}] has no registered handler.");
14101412
}
14111413

1412-
return $handler($instance, $this);
1414+
return $handler($instance, $this, $type);
14131415
}
14141416

14151417
/**

tests/Container/ContainerTest.php

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,17 @@ public function testLazyObjects()
236236
$this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class));
237237
}
238238

239+
public function testObjectWithLazyDependencies()
240+
{
241+
$container = new Container;
242+
$container->bind(IContainerContractStub::class, ContainerImplementationStub::class);
243+
$class = $container->make(ClassWithLazyDependencies::class);
244+
$this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class));
245+
$this->assertTrue((new ReflectionClass(ContainerDependentStub::class))->isUninitializedLazyObject($class->stubby));
246+
$this->assertTrue($class->stubbyIsSet());
247+
$this->assertFalse((new ReflectionClass($class))->isUninitializedLazyObject($class));
248+
}
249+
239250
public function testContainerIsPassedToResolvers()
240251
{
241252
$container = new Container;
@@ -1121,9 +1132,7 @@ class WildcardConcrete implements WildcardOnlyInterface
11211132
{
11221133
}
11231134

1124-
/*
1125-
* The order of these attributes matters because we want to ensure we only fallback to '*' when there's no more specific environment.
1126-
*/
1135+
// The order of these attributes matters because we want to ensure we only fallback to '*' when there's no more specific environment.
11271136
#[Bind(FallbackConcrete::class)]
11281137
#[Bind(ProdConcrete::class, environments: 'prod')]
11291138
interface WildcardAndProdInterface
@@ -1243,3 +1252,17 @@ public function stubbyIsSet(): bool
12431252
return isset($this->stubby);
12441253
}
12451254
}
1255+
1256+
class ClassWithLazyDependencies
1257+
{
1258+
public function __construct(
1259+
#[Lazy]
1260+
public ContainerDependentStub $stubby
1261+
) {
1262+
}
1263+
1264+
public function stubbyIsSet(): bool
1265+
{
1266+
return isset($this->stubby);
1267+
}
1268+
}

0 commit comments

Comments
 (0)