Skip to content

Commit

Permalink
Merge pull request #11 from ytake/feature/patch-1
Browse files Browse the repository at this point in the history
fiexd lock
  • Loading branch information
ytake authored Aug 22, 2018
2 parents 69f166a + 77d95ab commit 17ad184
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 37 deletions.
21 changes: 10 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,22 +136,21 @@ use Ytake\HHContainer\ServiceFactory;
use Ytake\HHContainer\FactoryContainer;
use Ytake\HHContainer\FactoryInterface;
final class StdClassFactory implements FactoryInterface {
const type T = stdClass;
public function provide(FactoryContainer $container): this::T {
return new \stdClass();
class StringFactory implements FactoryInterface {
const type T = string;
public function provide(FactoryContainer $_container): StringFactory::T {
return 'testing';
}
public function name(): string {
return 'stdClass';
}
public function scope(): Scope {
return Scope::Singleton;
}
public function name(): string {
return 'testing'
}
}
$factory = new ServiceFactory(new FactoryContainer());
$factory->registerFactory(new StdClassFactory());
$factory->create(\stdClass::class);
$factory->registerFactory(new StringFactory());
$factory->create('testing');
```
30 changes: 19 additions & 11 deletions src/FactoryContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ enum Scope : int {
type TServiceModule = classname<ServiceModule>;
type TCallable = (function(FactoryContainer): mixed);

use function is_null;
use function call_user_func;
use function sprintf;
use function array_key_exists;

/**
* simple light weight service locator container
* not supported autowiring
Expand Down Expand Up @@ -66,11 +71,14 @@ public function parameters(
public function get($id): mixed {
if ($this->has($id)) {
$resolved = $this->mapper->get($id);
if (!\is_null($resolved)) {
if (!is_null($resolved)) {
if ($resolved->firstKey() === Scope::Singleton) {
return $this->shared($id);
}
return \call_user_func($resolved->firstValue(), $this);
$callable = $resolved->firstValue();
if ($callable) {
return call_user_func($callable, $this);
}
}
}
try {
Expand All @@ -88,17 +96,17 @@ public function get($id): mixed {
}
} catch (\ReflectionException $e) {
throw new NotFoundException(
\sprintf('Identifier "%s" is not binding.', $id),
sprintf('Identifier "%s" is not binding.', $id),
);
}
throw new ContainerException(\sprintf('Error retrieving "%s"', $id));
throw new ContainerException(sprintf('Error retrieving "%s"', $id));
}

<<__Memoize>>
protected function shared(string $id): mixed {
$shared = $this->mapper->at($id);
$call = $shared->firstValue();
if(!\is_null($call)) {
if(!is_null($call)) {
return call_user_func($call, $this);
}
}
Expand Down Expand Up @@ -129,11 +137,11 @@ public function registerModule(TServiceModule $moduleClassName): void {
}
}

public function lockModule(): Iterator<void> {
$this->locked = true;
public function lockModule(): void {
foreach ($this->modules->getIterator() as $iterator) {
yield (new $iterator())->provide($this);
(new $iterator())->provide($this);
}
$this->locked = true;
}

protected function resolveConstructorParameters(
Expand All @@ -143,8 +151,8 @@ protected function resolveConstructorParameters(
$r = Vector{};
$parameters = $constructor->getParameters();
foreach ($parameters as $parameter) {
if (\array_key_exists($id, $this->parameters)) {
if (\array_key_exists($parameter->getName(), $this->parameters[$id])) {
if (array_key_exists($id, $this->parameters)) {
if (array_key_exists($parameter->getName(), $this->parameters[$id])) {
$r->add(call_user_func(
$this->parameters[$id][$parameter->getName()],
$this,
Expand All @@ -155,7 +163,7 @@ protected function resolveConstructorParameters(
return $r;
}

public function callable(Invokable $invokable): mixed {
public function callable(MethodCallIntreface $invokable): mixed {
return $invokable->proceed();
}
}
2 changes: 2 additions & 0 deletions src/FactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ interface FactoryInterface {
public function provide(FactoryContainer $container): this::T;

public function scope(): Scope;

public function name(): string;
}
24 changes: 24 additions & 0 deletions src/MethodCallIntreface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?hh // strict

/**
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*
* Copyright (c) 2017-2018 Yuuki Takezawa
*
*/

namespace Ytake\HHContainer;

interface MethodCallIntreface {

public function proceed(): mixed;
}
3 changes: 2 additions & 1 deletion src/Invokable.php → src/MethodCaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
* Copyright (c) 2017-2018 Yuuki Takezawa
*
*/

namespace Ytake\HHContainer;

class Invokable {
class MethodCaller implements MethodCallIntreface {

public function __construct(
protected mixed $instance,
Expand Down
8 changes: 3 additions & 5 deletions src/ServiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

use function is_null;
use function sprintf;
use function get_class;
type FactoryType = classname<FactoryInterface>;

class ServiceFactory {

Expand All @@ -31,10 +29,10 @@ public function __construct(
) {}

public function registerFactory(FactoryInterface $factory): void {
$this->factories->add(Pair{get_class($factory), $factory});
$this->factories->add(Pair{$factory->name(), $factory});
}

public function create(FactoryType $factoryName): FactoryType::T {
public function create(string $factoryName): FactoryInterface::T {
$resolve = $this->factories->get($factoryName);
if (!is_null($resolve)) {
if ($resolve->scope() === Scope::Singleton) {
Expand All @@ -48,7 +46,7 @@ public function create(FactoryType $factoryName): FactoryType::T {
}

<<__Memoize>>
protected function createShared(FactoryType $factoryName): FactoryType::T {
protected function createShared(string $factoryName): FactoryInterface::T {
return $this->factories
->at($factoryName)
->provide($this->container);
Expand Down
22 changes: 16 additions & 6 deletions tests/FactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,29 @@ public function testShouldReturnExpectValues(): void
{
$factory = new ServiceFactory(new FactoryContainer());
$factory->registerFactory(new StringFactory());
$this->assertSame('testing', $factory->create(StringFactory::class));
$this->assertSame('testing', $factory->create('testing'));
}

public function testShouldReturnStdClass(): void
{
$factory = new ServiceFactory(new FactoryContainer());
$factory->registerFactory(new MockClassFactory());
$i = $factory->create(MockClassFactory::class);
$this->assertSame(1, $i->getT());
$this->assertInstanceOf(MockClass::class, $factory->create(MockClassFactory::class));
$this->assertSame($factory->create(MockClassFactory::class), $factory->create(MockClassFactory::class));
$i = $factory->create(MockClass::class);
$this->assertInstanceOf(MockClass::class, $i);
if($i instanceof MockClass) {
$this->assertSame(1, $i->getT());
}
$this->assertInstanceOf(MockClass::class, $factory->create(MockClass::class));
$this->assertSame($factory->create(MockClass::class), $factory->create(MockClass::class));
}
}

class StringFactory implements FactoryInterface {
const type T = string;
public function provide(FactoryContainer $_container): StringFactory::T {
public function provide(FactoryContainer $_container): this::T {
return 'testing';
}
public function name(): string {
return 'testing';
}
public function scope(): Scope {
Expand All @@ -45,6 +51,10 @@ public function provide(FactoryContainer $_container): this::T {
public function scope(): Scope {
return Scope::Singleton;
}

public function name(): string {
return MockClass::class;
}
}

class MockClass {
Expand Down
6 changes: 3 additions & 3 deletions tests/InvokableTest.php → tests/MethodCallerTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?hh // strict

use type Ytake\HHContainer\Invokable;
use type Ytake\HHContainer\MethodCaller;
use type Ytake\HHContainer\FactoryContainer;

class InvokableTest extends \PHPUnit\Framework\TestCase
Expand All @@ -11,12 +11,12 @@ public function testShouldReturnExpectValues(): void
$container->set(
TestingInvokable::class,
$container ==>
$container->callable(new Invokable(new TestingInvokable(), '__invoke', $container))
$container->callable(new MethodCaller(new TestingInvokable(), '__invoke', $container))
);
$container->set(
TestingInvokableTwo::class,
$container ==>
$container->callable(new Invokable(new TestingInvokableTwo(), 'execute'))
$container->callable(new MethodCaller(new TestingInvokableTwo(), 'execute'))
);
$this->assertSame(1, $container->get(TestingInvokable::class));
$this->assertSame('testing', $container->get(TestingInvokableTwo::class));
Expand Down

0 comments on commit 17ad184

Please sign in to comment.