Skip to content

Commit

Permalink
Merge pull request #4 from lion-packages/new
Browse files Browse the repository at this point in the history
feat: support for dependency injection by parameters or default param…
  • Loading branch information
Sleon4 authored Jan 19, 2024
2 parents bb80bad + 73084a6 commit 9afb567
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 25 deletions.
35 changes: 22 additions & 13 deletions src/DependencyInjection/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,38 +42,47 @@ public function getFiles(string $folder): array
return $files;
}

public function getNamespace(string $file, string $namespace, string $split): string
public function getNamespace(string $file, string $namespace, string $split = '/'): string
{
$splitFile = explode($split, $file);

return $this->str->of("{$namespace}{$splitFile[1]}")->replace("/", "\\")->replace('.php', '')->trim()->get();
}

private function getParameters(ReflectionMethod $method): array
private function getParameters(ReflectionMethod $method, array $params = []): array
{
return array_map(
fn($parameter) => $this->container->get($this->getParameterClassName($parameter)),
$method->getParameters()
);
$args = [];

foreach ($method->getParameters() as $parameter) {
if ($parameter->isDefaultValueAvailable()) {
$args[] = $parameter->getDefaultValue();
} else {
if (!empty($params[$parameter->getName()])) {
$args[] = $params[$parameter->getName()];
} else {
$args[] = $this->container->get($this->getParameterClassName($parameter));
}
}
}

return $args;
}

public function injectDependenciesMethod(object $object, string $method): mixed
public function injectDependenciesMethod(object $object, string $method, array $params = []): mixed
{
$method = (new ReflectionClass($object))->getMethod($method);

return $method->invoke($object, ...$this->getParameters($method));
return $method->invoke($object, ...$this->getParameters($method, $params));
}

public function injectDependencies(object $object): object
public function injectDependencies(object $object, array $params = []): object
{
$reflectionClass = new ReflectionClass($object);

foreach ($reflectionClass->getMethods() as $method) {
foreach ((new ReflectionClass($object))->getMethods() as $method) {
$docDocument = $method->getDocComment();

if (is_string($docDocument)) {
if ((bool) preg_match('/@required/', $docDocument)) {
$method->invoke($object, ...$this->getParameters($method));
$method->invoke($object, ...$this->getParameters($method, $params));
}
}
}
Expand Down
60 changes: 48 additions & 12 deletions tests/ContainerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

class ContainerTest extends Test
{
const STR = 'test';
const FOLDER = './tests/';
const PATH_FILE = './Provider/CustomClass.php';
const FILES = [
Expand Down Expand Up @@ -59,24 +60,57 @@ public function testGetNamespace(): void

public function testGetParameters(): void
{
$class = new class {
public function exampleMethod(FactoryProvider $factoryProvider): FactoryProvider
{
return $factoryProvider;
}
};

$parameters = $this->getPrivateMethod('getParameters', [new ReflectionMethod($class, 'exampleMethod')]);
$parameters = $this->getPrivateMethod(
'getParameters',
[new ReflectionMethod(new CustomClass(), 'setFactoryProvider')
]);

$this->assertIsArray($parameters);
$this->assertInstanceOf(FactoryProvider::class, reset($parameters));

$parameters = $this->getPrivateMethod(
'getParameters',
[new ReflectionMethod(new CustomClass(), 'setMultiple')
]);

$this->assertIsArray($parameters);

$first = reset($parameters);
$second = end($parameters);

$this->assertInstanceOf(FactoryProvider::class, $first);
$this->assertIsString($second);
$this->assertSame(self::STR, $second);
}

public function testInjectDependenciesMethod(): void
{
$returnValue = $this->container->injectDependenciesMethod($this->customClass, 'setFactoryProviderSecond');
/** @var FactoryProvider $factoryProvider */
$factoryProvider = $this->container->injectDependenciesMethod($this->customClass, 'setFactoryProviderSecond');

$this->assertInstanceOf(FactoryProvider::class, $factoryProvider);
}

public function testInjectDependenciesMethodWithMultipleArguments(): void
{
/** @var FactoryProvider $factoryProvider */
$factoryProvider = $this->container->injectDependenciesMethod($this->customClass, 'setMultiple');

$this->assertInstanceOf(FactoryProvider::class, $returnValue);
$this->assertInstanceOf(FactoryProvider::class, $factoryProvider);
$this->assertSame(self::STR, $factoryProvider->getStr());
}

public function testInjectDependenciesMethodWithMultipleArgumentsDefault(): void
{
/** @var FactoryProvider $factoryProvider */
$factoryProvider = $this->container->injectDependenciesMethod(
$this->customClass,
'setDefaults',
['str' => self::STR]
);

$this->assertInstanceOf(FactoryProvider::class, $factoryProvider);
$this->assertSame(self::STR, $factoryProvider->getStr());
}

public function testInjectDependencies(): void
Expand All @@ -91,8 +125,10 @@ public function testInjectDependencies(): void
public function testGetParameterClassName()
{
$reflectionParameter = new ReflectionParameter(self::REFLECTION_PARAMETERS, 'factoryProvider');
$result = $this->getPrivateMethod('getParameterClassName', [$reflectionParameter]);

$this->assertSame(FactoryProvider::class, $result);
/** @var FactoryProvider $factoryProvider */
$factoryProvider = $this->getPrivateMethod('getParameterClassName', [$reflectionParameter]);

$this->assertSame(FactoryProvider::class, $factoryProvider);
}
}
10 changes: 10 additions & 0 deletions tests/Provider/CustomClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,14 @@ public function setFactoryProviderSecond(FactoryProvider $factoryProvider): Fact
{
return $factoryProvider;
}

public function setMultiple(FactoryProvider $factoryProvider, string $str = 'test'): FactoryProvider
{
return $factoryProvider->setStr($str);
}

public function setDefaults(FactoryProvider $factoryProvider, string $str): FactoryProvider
{
return $factoryProvider->setStr($str);
}
}
13 changes: 13 additions & 0 deletions tests/Provider/FactoryProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,17 @@

class FactoryProvider
{
private string $str;

public function getStr(): string
{
return $this->str;
}

public function setStr(string $str): FactoryProvider
{
$this->str = $str;

return $this;
}
}

0 comments on commit 9afb567

Please sign in to comment.