Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6747907
commit 529147c
Showing
20 changed files
with
701 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace MarcelStrahl\Container\Delegator; | ||
|
||
interface DelegateInterface | ||
{ | ||
public function delegate(string $class): object; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace MarcelStrahl\Container\Delegator; | ||
|
||
use MarcelStrahl\Container\Factory\FactoryInterface; | ||
use MarcelStrahl\Container\ObjectBuilder\ObjectBuilderFactoryInterface; | ||
|
||
use function class_implements; | ||
use function in_array; | ||
use function method_exists; | ||
|
||
final class ObjectDelegator implements DelegateInterface | ||
{ | ||
public function __construct(private ObjectBuilderFactoryInterface $builderFactory) {} | ||
|
||
public function delegate(string $class): object | ||
{ | ||
$interfaces = class_implements($class); | ||
$isFactory = in_array(FactoryInterface::class, $interfaces, true); | ||
if (!$isFactory) { | ||
$isFactory = method_exists($class, '__invoke'); | ||
} | ||
|
||
$type = ObjectBuilderFactoryInterface::BUILDER_REFLECTION; | ||
if ($isFactory) { | ||
$type = ObjectBuilderFactoryInterface::BUILDER_FACTORY; | ||
} | ||
|
||
$builder = $this->builderFactory->factorize($type); | ||
|
||
return $builder->initialize($class); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
src/Exception/ObjectBuilderFactory/UnknownBuilderTypeException.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace MarcelStrahl\Container\Exception\ObjectBuilderFactory; | ||
|
||
use RuntimeException; | ||
|
||
final class UnknownBuilderTypeException extends RuntimeException | ||
{ | ||
public static function create(string $type): self | ||
{ | ||
return new self(sprintf('Unknown builder type detected. Given: "%s"', $type)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace MarcelStrahl\Container\Factory; | ||
|
||
use Psr\Container\ContainerInterface; | ||
|
||
/** | ||
* @author Marcel Strahl <info@marcel-strahl.de> | ||
*/ | ||
interface FactoryInterface | ||
{ | ||
public function factorize(ContainerInterface $container): object; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace MarcelStrahl\Container\ObjectBuilder; | ||
|
||
use MarcelStrahl\Container\Exception\NotFoundInContainerException; | ||
use MarcelStrahl\Container\Factory\FactoryInterface; | ||
use Psr\Container\ContainerInterface; | ||
|
||
use function class_exists; | ||
use function is_callable; | ||
use function method_exists; | ||
|
||
/** | ||
* @author Marcel Strahl <info@marcel-strahl.de> | ||
*/ | ||
final class FactoryBuilder implements ObjectBuilder | ||
{ | ||
public function __construct(private ContainerInterface $container, private ObjectBuilder $reflectionBuilder) {} | ||
|
||
public function initialize(callable|string $class): object | ||
{ | ||
if (is_callable($class)) { | ||
return $class($this->container); | ||
} | ||
|
||
if (!class_exists($class)) { | ||
throw NotFoundInContainerException::create($class); | ||
} | ||
|
||
$factory = $this->reflectionBuilder->initialize($class); | ||
if (method_exists($factory, '__invoke')) { | ||
|
||
return $factory->__invoke($this->container); | ||
} | ||
|
||
if (!$factory instanceof FactoryInterface) { | ||
throw NotFoundInContainerException::create($class); | ||
} | ||
|
||
return $factory->factorize($this->container); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace MarcelStrahl\Container\ObjectBuilder; | ||
|
||
use MarcelStrahl\Container\Exception\ObjectBuilderFactory\UnknownBuilderTypeException; | ||
use Psr\Container\ContainerInterface; | ||
use Webmozart\Assert\Assert; | ||
|
||
final class ObjectBuilderFactory implements ObjectBuilderFactoryInterface | ||
{ | ||
private ?ContainerInterface $container; | ||
|
||
public function __construct() | ||
{ | ||
$this->container = null; | ||
} | ||
|
||
/** | ||
* @psalm-param self::BUILDER_* $builderType | ||
* @throws UnknownBuilderTypeException | ||
*/ | ||
public function factorize(string $builderType): ObjectBuilder | ||
{ | ||
$container = $this->container; | ||
|
||
Assert::isInstanceOf( | ||
$container, | ||
ContainerInterface::class, | ||
'It is important that you set the container before calling `factorize`.', | ||
); | ||
|
||
$reflectionBuilder = new ReflectionBuilder(); | ||
return match ($builderType) { | ||
self::BUILDER_REFLECTION => $reflectionBuilder, | ||
self::BUILDER_FACTORY => new FactoryBuilder($container, $reflectionBuilder), | ||
default => throw UnknownBuilderTypeException::create($builderType), | ||
}; | ||
} | ||
|
||
public function setContainer(ContainerInterface $container): void | ||
{ | ||
$this->container = $container; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace MarcelStrahl\Container\ObjectBuilder; | ||
|
||
use MarcelStrahl\Container\Exception\ObjectBuilderFactory\UnknownBuilderTypeException; | ||
|
||
interface ObjectBuilderFactoryInterface | ||
{ | ||
public const BUILDER_REFLECTION = 'reflection'; | ||
public const BUILDER_FACTORY = 'factory'; | ||
|
||
/** | ||
* @psalm-param self::BUILDER_* $builderType | ||
* @throws UnknownBuilderTypeException | ||
*/ | ||
public function factorize(string $builderType): ObjectBuilder; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.