Skip to content

Commit

Permalink
feat: add optional params
Browse files Browse the repository at this point in the history
Signed-off-by: Fery Wardiyanto <ferywardiyanto@gmail.com>
  • Loading branch information
feryardiant committed Jun 20, 2020
1 parent b1b4410 commit 64024a3
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 4 deletions.
55 changes: 53 additions & 2 deletions src/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,65 @@ public function unset(string $id): void
/**
* {@inheritDoc}
*/
public function make(string $concrete, ?\Closure $condition = null)
public function make(string $concrete, ...$params)
{
$instance = $this->resolver->resolve($concrete);

list($args, $condition) = $this->assertParams($params);

if (null !== $condition) {
$instance = $condition($instance) ?? $instance;
}

return $this->resolver->handle($instance);
return $this->resolver->handle($instance, $args);
}

/**
* Assert $argumens and $condition by $params
*
* @param array $params
* @return array List of [$argumens, $condition]
*/
private function assertParams(array $params = []): array
{
$arguments = [];
$condition = null;

switch (count($params)) {
case 0:
// do nothing
break;
case 1:
$arguments = is_array($params[0]) ? $params[0] : [];
$condition = $params[0] instanceof \Closure ? $params[0] : null;

if (! is_array($params[0]) && ! ($params[0] instanceof \Closure)) {
throw new \InvalidArgumentException(
sprintf('Expect parameter 2 to be an array or Closure, %s given', gettype($params[0]))
);
}
break;
case 2:
if (! is_array($params[0])) {
throw new \InvalidArgumentException(
sprintf('Expect parameter 2 to be an array or Closure, %s given', gettype($params[0]))
);
}
if (! ($params[1] instanceof \Closure) && null !== $params[1]) {
throw new \InvalidArgumentException(
sprintf('Expect parameter 3 to be a Closure, %s given', gettype($params[0]))
);
}

$arguments = $params[0];
$condition = $params[1];
break;
default:
throw new \InvalidArgumentException(
sprintf('Could not accept more than 3 arguments, %d given', count($params))
);
}

return [$arguments, $condition];
}
}
22 changes: 20 additions & 2 deletions src/Container/ContainerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,27 @@ public function unset(string $id): void;
/**
* Resolve an instance without adding it to the stack.
*
* It's possible to add 2nd parameter as an array and it will pass it to
* `Resolver::handle($instance, $args)`. While if it was a Closure, it will
* treaten as condition.
*
* ```php
* // Treat 2nd parameter as arguments
* $container->make(SomeClass::class, ['foo', 'bar'])
*
* $container->make(SomeClass::class, function ($instance) {
* // a condition
* })
*
* // Treat 2nd parameter as arguments and 3rd as condition
* $container->make(SomeClass::class, ['foo', 'bar'], function ($instance) {
* // a condition
* })
* ```
*
* @param string $concrete
* @param null|\Closure $condition
* @param null|array|\Closure ...$args
* @return mixed
*/
public function make(string $concrete, ?\Closure $condition = null);
public function make(string $concrete, ...$args);
}
38 changes: 38 additions & 0 deletions test/spec/Container.spec.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,42 @@
});
})->toThrow(new BadMethodCallException);
});

it('Shuold accept 2nd and 3rd params', function () {
// Dependencies.
$this->c->set('dummy', Dummy::class);
$this->c->set(AbstractFoo::class, ConcreteBar::class);

expect(
$this->c->make(Stubs\SomeClass::class, function ($instance) {
return [$instance, 'shouldCalled'];
})
)->toEqual('a value');

expect(function () {
$this->c->make(Stubs\SomeClass::class, 'string');
})->toThrow(new InvalidArgumentException);

expect(function () {
$this->c->make(Stubs\SomeClass::class, 'string', null);
})->toThrow(new InvalidArgumentException);

expect(function () {
$this->c->make(Stubs\SomeClass::class, ['string'], 'condition');
})->toThrow(new InvalidArgumentException);

expect(function () {
$this->c->make(Stubs\SomeClass::class, ['string'], 'condition', 'more');
})->toThrow(new InvalidArgumentException);

expect(
$this->c->make(Stubs\SomeClass::class, ['new value'], null)
)->toBeAnInstanceOf(Stubs\CertainInterface::class);

expect(
$this->c->make(Stubs\SomeClass::class, ['new value'], function ($instance) {
return [$instance, 'shouldCalled'];
})
)->toEqual('new value');
});
});
5 changes: 5 additions & 0 deletions test/stub/SomeClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,9 @@ public function handle(AbstractFoo $dummy): string
{
return $dummy->lorem();
}

public function shouldCalled($param = 'a value')
{
return $param;
}
}

0 comments on commit 64024a3

Please sign in to comment.