Skip to content

Commit c702a5b

Browse files
committed
Bind
1 parent 89207fb commit c702a5b

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Illuminate\Container\Attributes;
4+
5+
use Attribute;
6+
7+
#[Attribute(Attribute::TARGET_CLASS)]
8+
class Bind
9+
{
10+
/**
11+
* @param class-string $concrete
12+
*/
13+
public function __construct(
14+
public string $concrete,
15+
) {
16+
}
17+
}

src/Illuminate/Container/Container.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use ArrayAccess;
66
use Closure;
77
use Exception;
8+
use Illuminate\Container\Attributes\Bind;
89
use Illuminate\Container\Attributes\Scoped;
910
use Illuminate\Container\Attributes\Singleton;
1011
use Illuminate\Contracts\Container\BindingResolutionException;
@@ -961,7 +962,19 @@ protected function getConcrete($abstract)
961962
return $this->bindings[$abstract]['concrete'];
962963
}
963964

964-
return $abstract;
965+
$attributes = [];
966+
try {
967+
$attributes = (new ReflectionClass($abstract))->getAttributes(Bind::class);
968+
} catch (ReflectionException) {
969+
}
970+
971+
if ($attributes === []) {
972+
return $abstract;
973+
}
974+
975+
$this->bind($abstract, $attributes[0]->newInstance()->concrete);
976+
977+
return $this->bindings[$abstract]['concrete'];
965978
}
966979

967980
/**

tests/Container/ContainerTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Illuminate\Tests\Container;
44

55
use Attribute;
6+
use Illuminate\Container\Attributes\Bind;
67
use Illuminate\Container\Attributes\Scoped;
78
use Illuminate\Container\Attributes\Singleton;
89
use Illuminate\Container\Container;
@@ -766,6 +767,29 @@ public function testContainerScopedAttribute()
766767
$this->assertNotSame($firstInstantiation, $thirdInstantiation);
767768
}
768769

770+
public function testBindInterfaceToSingleton()
771+
{
772+
$container = new Container;
773+
$firstInstantiation = $container->get(ContainerBindSingletonTestInterface::class);
774+
$secondInstantiation = $container->get(ContainerBindSingletonTestInterface::class);
775+
776+
$this->assertSame($firstInstantiation, $secondInstantiation);
777+
}
778+
779+
public function testBindInterfaceToScoped()
780+
{
781+
$container = new Container;
782+
$firstInstantiation = $container->get(ContainerBindScopedTestInterface::class);
783+
$secondInstantiation = $container->get(ContainerBindScopedTestInterface::class);
784+
785+
$this->assertSame($firstInstantiation, $secondInstantiation);
786+
787+
$container->forgetScopedInstances();
788+
789+
$thirdInstantiation = $container->get(ContainerBindScopedTestInterface::class);
790+
$this->assertNotSame($firstInstantiation, $thirdInstantiation);
791+
}
792+
769793
// public function testContainerCanCatchCircularDependency()
770794
// {
771795
// $this->expectException(\Illuminate\Contracts\Container\CircularDependencyException::class);
@@ -935,3 +959,13 @@ class ContainerSingletonAttribute
935959
class ContainerScopedAttribute
936960
{
937961
}
962+
963+
#[Bind(ContainerSingletonAttribute::class)]
964+
interface ContainerBindSingletonTestInterface
965+
{
966+
}
967+
968+
#[Bind(ContainerScopedAttribute::class)]
969+
interface ContainerBindScopedTestInterface
970+
{
971+
}

0 commit comments

Comments
 (0)