GithubHelp home page GithubHelp logo

filecage / creator Goto Github PK

View Code? Open in Web Editor NEW
5.0 3.0 1.0 174 KB

creator is a simple PHP dependency injection / service container that works with typehints and powers www.thomann.de

License: MIT License

PHP 100.00%
php dependency-injection dependency-resolver service-container typehints registry auto-wire psr-11

creator's People

Contributors

filecage avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

pleinx

creator's Issues

Make configurable UninstantiableFactoryProvider

Currently all unistantiable dependencies get the same Factory name pattern. This should be a configurable callable value per ResourceRegistry.

Default could be no provider given, resulting in the functionality being disabled.

Faster lookup of fulfilling instances

As of now, Creator iterates over each registered class resource to find out whether it might be a fulfilling instance (implementing an uninstantiable).

Storing the implementing interfaces and abstracts during registration might cause faster lookups. (But also slower registration times - probably requires some measuring).

Unresolvable Exceptions should be more verbose

Whenever an Creator\Exceptions\Unresolvable occurs because of an unresolvable dependency, it does not tell enough details on why it failed; it's missing the Information of the actual unresolvable dependency.

Draft for new Exception:

Class Name

Creator\Exceptions\UnresolvableInnerDependency extends Creator\Exceptions\Unresolvable

Message

Dependency Foo\Bar\Baz can not be resolved: Inner dependency Foo\Bar\Baz\Dependency demands Foo\Bar\Baz\Dependency\Inexistent as $parameterName, but the resource is unknown

Ensure complete dependency tree resolution when using injected instances

The Creation class forces an instance if the requested resource depends on an injected instance, but only checks the first level - i.e. the direct dependants of the requested resource.

To ensure deterministic results, Creator should check the complete dependency tree (i.e. any dependency of the dependencies) and re-create any resource that depends on an injected instance.

An example to clarify the issue:

class Foo {
    function __construct(Bar $bar) {
         $this->bar = $bar;
    }
}

class Bar {
    function __construct(Baz $baz) {
        $this->baz = $baz;
    }
}

class Baz {
    function __construct($bax = 'Hello World') {
        $this->bax = $bax;
    }
}

$instanceWithDefaultValue = $creator->create(Foo::class);

// This should output `Hello World`
echo $instanceWithDefaultValue->bar->baz->bax;

$anotherBaz = new Baz('Goodbye cruel world');
$instanceWithCustomValue = $creator->createInjected(Foo::class)->with($anotherBaz)->create();

// This should output `Goodbye cruel world` but actually outputs `Hello World`
echo $instanceWithCustomValue->bar->baz->bax;

Internally, ->create() checks whether a dependency of the class (Foo) is contained in the injected resource registry. That check is misleading because it does not consider that Foo might have a dependency of the injected class Baz.

Resolve classes if callable has no object-context

It is unsupported to pass a callable to invoke() that is missing the object context:

if (is_array($callable) && count($callable) === 2) {
// todo: Creator should resolve the object if we know the class name
if (!is_object($callable[0])) {
throw new Unresolvable('Unable to handle invokation of object-context callable: no object given on callable index 0');
}

Creator should resolve the object (if it's non-static) and then call the invokable instead of throwing an exception.

Example test case that should pass:

class Foo {
    function __construct($bar) {
        $this->bar = $bar;
    }
}

class BarTransformer {
    function transform ($bar) {
        return strtoupper($bar);
    }
}

class AnyClass {
    static function bax (Foo $foo, BarTransformer $barTransformer) {
        return $barTransformer->transform($foo->bar);
    }

    function __construct(Foo $foo) {
        $this->foo = $foo;
    }

    function bar (BarTransformer $barTransformer) {
        return $barTransformer->transform($this->foo->bar);
    }
}

$creator = new Creator();
$creator->registerClassResource(new Foo('hello world'));

echo $creator->invoke(['AnyClass', 'bax']);
echo $creator->invoke(['AnyClass', 'bar']);

Should output

HELLO WORLD

twice, the first invocation should not register a class resource as the method is only called statically.

Allow lazy factories

Following #3, we should allow registration of lazy factories, i.e. instances of Creator\Interfaces\Factory which are only being created once the factory is being called.

Improve README.md

Improve README.md to ensure easier understanding of usage.

  • Add public API reference
  • Separate internal dependency resolving logic from user interface; maybe describe internal processes in wiki?
  • Easier wording

Factory result of interface factories has insufficient caching

Affected Creator Version

0.8.0

Reproduce Scenario

<?php

interface FoobarInterface {
}

class Foobar implements FoobarInterface {
    function __construct() {
        echo 'Hello ';
    }
}

$creator = new Creator\Creator();

$creator->registerFactory(function() { return new Foobar(); }, FoobarInterface::class);

$foobar1 = $creator->create(FoobarInterface::class);
$foobar2 = $creator->create(FoobarInterface::class);

if ($foobar1 === $foobar2) {
    echo ' World!';
} else {
    echo ' Fail!';
}

Expected Output

Hello World!

Actual Output

Hello Hello Fail!

Allow registering factories explicitly

Proposed interface:
$creator->registerFactory(string $classResourceKey, callable $factory | instanceof Interfaces\Factory) : object

In call stack: after ResourceRegistry, before any creation routine

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.