Skip to content

Commit

Permalink
feat: add autowire/autodiscovery/auto-initialization of interfaces to…
Browse files Browse the repository at this point in the history
… classes (#501)
  • Loading branch information
Jeroen-G authored Oct 1, 2024
1 parent 257cacb commit 1572122
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/Tempest/Container/src/Autowire.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Tempest\Container;

use Attribute;

#[Attribute(Attribute::TARGET_CLASS)]
final class Autowire
{
}
63 changes: 63 additions & 0 deletions src/Tempest/Container/src/AutowireDiscovery.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

declare(strict_types=1);

namespace Tempest\Container;

use Tempest\Core\Discovery;
use Tempest\Core\HandlesDiscoveryCache;
use Tempest\Reflection\ClassReflector;

/**
* @property GenericContainer $container
*/
final class AutowireDiscovery implements Discovery
{
use HandlesDiscoveryCache;

public function __construct(
private readonly Container $container,
) {
}

public function discover(ClassReflector $class): void
{
$autowire = $class->getAttribute(Autowire::class);

if ($autowire === null) {
return;
}

if ($class->getAttribute(Singleton::class) !== null) {
$this->discoverAsSingleton($class);
} else {
$this->discoverAsDefinition($class);
}
}

private function discoverAsSingleton(ClassReflector $class): void
{
$interfaces = $class->getReflection()->getInterfaceNames();
foreach ($interfaces as $interface) {
$this->container->singleton($interface, fn (Container $container) => $container->get($class->getName()));
}
}

private function discoverAsDefinition(ClassReflector $class): void
{
$interfaces = $class->getReflection()->getInterfaceNames();
foreach ($interfaces as $interface) {
$this->container->register($interface, fn (Container $container) => $container->get($class->getName()));
}
}

public function createCachePayload(): string
{
return serialize($this->container->getDefinitions());
}

public function restoreCachePayload(Container $container, string $payload): void
{
$this->container->setDefinitions(unserialize($payload));
}
}
12 changes: 12 additions & 0 deletions src/Tempest/Container/src/GenericContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ public function __construct(
) {
}

public function setDefinitions(array $definitions): self
{
$this->definitions = new ArrayIterator($definitions);

return $this;
}

public function setInitializers(array $initializers): self
{
$this->initializers = new ArrayIterator($initializers);
Expand All @@ -50,6 +57,11 @@ public function setDynamicInitializers(array $dynamicInitializers): self
return $this;
}

public function getDefinitions(): array
{
return $this->definitions->getArrayCopy();
}

public function getInitializers(): array
{
return $this->initializers->getArrayCopy();
Expand Down

0 comments on commit 1572122

Please sign in to comment.