Skip to content

Commit

Permalink
add: DI singleton with tests
Browse files Browse the repository at this point in the history
  • Loading branch information
twent committed Jul 11, 2023
1 parent 17b5091 commit f1af30a
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Alpha version (in development).

Features:
- DI Container (thanks to Brent Rose)
- Request
- Response with content type changing (Json by default)
- ResponseEmitter
Expand Down
5 changes: 5 additions & 0 deletions core/DI/Contracts/Container.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
<?php

/**
* @author Brent Rose (https://github.com/brendt)
*/

declare(strict_types=1);

namespace Twent\Framework\DI\Contracts;

interface Container
{
public function register(string $className, callable $definition): self;
public function singleton(string $className, callable $definition): self;

/**
* @template TClassName
Expand Down
20 changes: 20 additions & 0 deletions core/DI/GenericContainer.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<?php

/**
* @author Brent Rose (https://github.com/brendt)
*/

declare(strict_types=1);

namespace Twent\Framework\DI;
Expand All @@ -12,6 +16,7 @@
final class GenericContainer implements Container
{
private array $definitions = [];
private array $singletons = [];

public function register(string $className, callable $definition): Container
{
Expand All @@ -20,11 +25,26 @@ public function register(string $className, callable $definition): Container
return $this;
}

public function singleton(string $className, callable $definition): Container
{
$this->definitions[$className] = function () use ($className, $definition) {
$instance = $definition($this);
$this->singletons[$className] = $instance;
return $instance;
};

return $this;
}

/**
* @inheritDoc
*/
public function get(string $className): object
{
if ($instance = ($this->singletons[$className] ?? null)) {
return $instance;
}

$definition = $this->definitions[$className] ?? $this->autowire(...);

return $definition($className);
Expand Down
14 changes: 14 additions & 0 deletions tests/Feature/DI/GenericContainerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,18 @@ public function testContainerAutowire(): void

$this->assertInstanceOf(Bar::class, $bar);
}

public function testSingleton(): void
{
$container = new GenericContainer();

$container->singleton(SingletonExample::class, fn() => new SingletonExample());
$instance = $container->get(SingletonExample::class);

$this->assertInstanceOf(SingletonExample::class, $instance);
$this->assertEquals(1, $instance::$count);

$this->assertInstanceOf(SingletonExample::class, $instance);
$this->assertEquals(1, $instance::$count);
}
}
15 changes: 15 additions & 0 deletions tests/Feature/DI/SingletonExample.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Tests\Twent\Framework\Feature\DI;

final class SingletonExample
{
public static int $count = 0;

public function __construct()
{
self::$count += 1;
}
}

0 comments on commit f1af30a

Please sign in to comment.