Skip to content

Commit 09ced7a

Browse files
authored
feat(container): add has and unregister (#840)
1 parent 6747d2c commit 09ced7a

File tree

5 files changed

+110
-0
lines changed

5 files changed

+110
-0
lines changed

src/Tempest/Container/src/Container.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ interface Container
1212
{
1313
public function register(string $className, callable $definition): self;
1414

15+
public function unregister(string $className): self;
16+
1517
public function singleton(string $className, mixed $definition, ?string $tag = null): self;
1618

1719
public function config(object $config): self;
@@ -23,6 +25,8 @@ public function config(object $config): self;
2325
*/
2426
public function get(string $className, ?string $tag = null, mixed ...$params): mixed;
2527

28+
public function has(string $className, ?string $tag = null): bool;
29+
2630
public function invoke(MethodReflector|FunctionReflector|callable|string $method, mixed ...$params): mixed;
2731

2832
/**

src/Tempest/Container/src/GenericContainer.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,20 @@ public function register(string $className, callable $definition): self
8181
return $this;
8282
}
8383

84+
public function unregister(string $className): self
85+
{
86+
unset($this->definitions[$className]);
87+
unset($this->singletons[$className]);
88+
89+
return $this;
90+
}
91+
92+
public function has(string $className, ?string $tag = null): bool
93+
{
94+
return isset($this->definitions[$className])
95+
|| isset($this->singletons[$this->resolveTaggedName($className, $tag)]);
96+
}
97+
8498
public function singleton(string $className, mixed $definition, ?string $tag = null): self
8599
{
86100
$className = $this->resolveTaggedName($className, $tag);

src/Tempest/Container/tests/ContainerTest.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PHPUnit\Framework\TestCase;
88
use ReflectionClass;
99
use Tempest\Container\Exceptions\CannotAutowireException;
10+
use Tempest\Container\Exceptions\CannotInstantiateDependencyException;
1011
use Tempest\Container\Exceptions\CannotResolveTaggedDependency;
1112
use Tempest\Container\Exceptions\CircularDependencyException;
1213
use Tempest\Container\Exceptions\InvalidCallableException;
@@ -29,8 +30,10 @@
2930
use Tempest\Container\Tests\Fixtures\ContainerObjectEInitializer;
3031
use Tempest\Container\Tests\Fixtures\DependencyWithBuiltinDependencies;
3132
use Tempest\Container\Tests\Fixtures\DependencyWithTaggedDependency;
33+
use Tempest\Container\Tests\Fixtures\ImplementsInterfaceA;
3234
use Tempest\Container\Tests\Fixtures\InjectA;
3335
use Tempest\Container\Tests\Fixtures\InjectB;
36+
use Tempest\Container\Tests\Fixtures\InterfaceA;
3437
use Tempest\Container\Tests\Fixtures\IntersectionInitializer;
3538
use Tempest\Container\Tests\Fixtures\InvokableClass;
3639
use Tempest\Container\Tests\Fixtures\InvokableClassWithParameters;
@@ -390,4 +393,72 @@ public function test_inject(): void
390393

391394
$this->assertInstanceOf(InjectB::class, $a->getB());
392395
}
396+
397+
public function test_unregister(): void
398+
{
399+
$container = new GenericContainer();
400+
401+
$container->register(InterfaceA::class, fn () => new ImplementsInterfaceA());
402+
403+
$this->assertInstanceOf(ImplementsInterfaceA::class, $container->get(InterfaceA::class));
404+
405+
$container->unregister(InterfaceA::class);
406+
407+
$this->expectException(CannotInstantiateDependencyException::class);
408+
409+
$container->get(InterfaceA::class);
410+
}
411+
412+
public function test_unregister_singleton(): void
413+
{
414+
$container = new GenericContainer();
415+
416+
$container->singleton(InterfaceA::class, $instance = new ImplementsInterfaceA());
417+
418+
$this->assertInstanceOf(ImplementsInterfaceA::class, $container->get(InterfaceA::class));
419+
$this->assertSame($instance, $container->get(InterfaceA::class));
420+
421+
$container->unregister(InterfaceA::class);
422+
423+
$this->expectException(CannotInstantiateDependencyException::class);
424+
425+
$container->get(InterfaceA::class);
426+
}
427+
428+
public function test_has(): void
429+
{
430+
$container = new GenericContainer();
431+
432+
$this->assertFalse($container->has(InterfaceA::class));
433+
434+
$container->register(InterfaceA::class, fn () => new ImplementsInterfaceA());
435+
436+
$this->assertTrue($container->has(InterfaceA::class));
437+
}
438+
439+
public function test_has_singleton(): void
440+
{
441+
$container = new GenericContainer();
442+
443+
$this->assertFalse($container->has(InterfaceA::class));
444+
445+
$container->singleton(InterfaceA::class, new ImplementsInterfaceA());
446+
447+
$this->assertTrue($container->has(InterfaceA::class));
448+
}
449+
450+
public function test_has_tagged_singleton(): void
451+
{
452+
$container = new GenericContainer();
453+
454+
$this->assertFalse($container->has(TaggedDependency::class, 'web'));
455+
456+
$container->singleton(
457+
TaggedDependency::class,
458+
new TaggedDependency('web'),
459+
tag: 'web',
460+
);
461+
462+
$this->assertTrue($container->has(TaggedDependency::class, 'web'));
463+
}
393464
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Container\Tests\Fixtures;
6+
7+
final class ImplementsInterfaceA implements InterfaceA
8+
{
9+
public function __invoke(): void
10+
{
11+
}
12+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Container\Tests\Fixtures;
6+
7+
interface InterfaceA
8+
{
9+
}

0 commit comments

Comments
 (0)