{"id":37008582,"url":"https://github.com/filecage/creator","last_synced_at":"2026-01-14T00:50:10.831Z","repository":{"id":45875563,"uuid":"48396413","full_name":"filecage/creator","owner":"filecage","description":"creator is a simple PHP dependency injection / service container that works with typehints and powers www.thomann.de","archived":false,"fork":false,"pushed_at":"2023-06-01T12:58:55.000Z","size":174,"stargazers_count":5,"open_issues_count":3,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-03T06:41:58.310Z","etag":null,"topics":["auto-wire","dependency-injection","dependency-resolver","php","psr-11","registry","service-container","typehints"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/filecage.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-21T22:00:38.000Z","updated_at":"2024-01-15T12:39:42.000Z","dependencies_parsed_at":"2022-09-05T06:50:49.310Z","dependency_job_id":null,"html_url":"https://github.com/filecage/creator","commit_stats":null,"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/filecage/creator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filecage%2Fcreator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filecage%2Fcreator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filecage%2Fcreator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filecage%2Fcreator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/filecage","download_url":"https://codeload.github.com/filecage/creator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/filecage%2Fcreator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28407174,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T00:40:43.272Z","status":"ssl_error","status_checked_at":"2026-01-14T00:40:42.636Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auto-wire","dependency-injection","dependency-resolver","php","psr-11","registry","service-container","typehints"],"created_at":"2026-01-14T00:50:10.733Z","updated_at":"2026-01-14T00:50:10.813Z","avatar_url":"https://github.com/filecage.png","language":"PHP","readme":"# creator\ncreator is a simple PHP dependency injection that works with typehints and Reflection classes\n\n* [Installation](#installation)\n* [Testing](#testing)\n* [Basic Usage](#basic-usage)\n* [PSR-11 Container Usage](#psr-11-container-usage)\n* [Injected Instances](#injected-instances)\n* [Invoke Closures / Callables](#invoke-closures--callables)\n* [Factories](#factories)\n* [Uninstantiable Classes](#uninstantiable-classes)\n* [Registering Resources](#registering-resources)\n* [Exceptions](#exceptions)\n\n## Installation\nvia [composer](https://getcomposer.org/)\n````bash\n$ composer require tholabs/creator\n````\n\n## Testing\nvia [phpunit](https://phpunit.de/)\n````bash\n$ phpunit\n````\n\n\n## Basic Usage\n### With class constant\n````php\n\u003c?php\n    $creator = new \\Creator\\Creator;\n    $myInstance = $creator-\u003ecreate(MyClass::class);\n````\n### With recursive dependencies\nassuming our `MyClass` looks like this:\n````php\n\u003c?php\n    class MyClass {\n        function __construct(AnotherClass $anotherClass) {\n            $this-\u003eanotherClass = $anotherClass;\n        }\n    }\n````\nCreator will walk up the dependency tree and resolve any class which has no known instance yet.\n\n## PSR-11 Container usage\nCreator supports the [PSR-11](https://www.php-fig.org/psr/psr-11/) `psr/container` standard.\n```php\n\u003c?php\n\n    $container = new Creator\\Container(new Creator\\Creator());\n    $myInstance = $container-\u003eget(MyClass::class);\n```\n\nThe `$container-\u003ehas()` will return `true` if:\n* a primitive resource with given `$identifier` has been registered using `$creator-\u003eregisterPrimitiveResource()`\n* a class resource with given `$identifier` has been registered using `$creator-\u003eregisterClassResource()`\n* a class resource factory for `$identifier` has been registered using `$creator-\u003eregisterFactory()`\n* `$identifier` is an interface or abstract class that can be fulfilled (because another instance implementing or inheriting has been registered earlier)\n\nIt will not return `true` if a given `$identifier` _might be_ instantiable. \n\n## Injected Instances\nCreator is able to use an independent resource registry for a single creation process.\n````php\n\u003c?php\n    $anotherClass = new AnotherClass();\n    \n    $creator = new Creator\\Creator;\n    $myClass = $creator-\u003ecreateInjected(MyClass::class)-\u003ewith($anotherClass)-\u003ecreate();\n    \n    if ($myClass-\u003eanotherClass === $anotherClass) {\n        echo 'We are the same!';\n    }\n````\nAny other dependency of MyClass is being resolved the usual way (i.e. looked up via the ResourceRegistry and, if there is no instance yet, it's being created with the same injected resources.)\nCreator collects dependency signatures and thus only re-creates instances that really require an injected dependency.\n\n## Invoke Closures / Callables\nCreator is able to resolve parameters of closures and callables (invokables). It supports closures and method-context array callables with the object at index 0 (using the class name at index 0 is currently not supported and will cause Creator to throw an `Unresolvable` exception).\n\nInjecting instances is supported as well.\n````php\n\u003c?php\n\n    // Default invocation\n    $creator-\u003einvoke(function(SimpleClass $simpleClass) {\n        if ($simpleClass instanceof SimpleClass) {\n            echo 'Everything works as expected.';\n        }\n    }\n    \n    // Injected invocation\n    $simpleClassRoleModel = new SimpleClass();\n    $creator-\u003einvokeInjected(function(SimpleClass $simpleClass) use($simpleClassRoleModel) {\n        if ($simpleClass === $simpleClassRoleModel) {\n            echo 'Injection is great';\n        }\n    })-\u003ewith($simpleClassRoleModel)-\u003einvoke();\n````\n\n## Factories\nIf you have resources that can not be created without additional logic, but also should only be created once another component depends them, you can register a factory for this factory.\nA factory can be a callable, an instance of `Creator\\Interfaces\\Factory` or a class string of a Factory (see [lazy bound factories](#lazy-bound-factories)) and can be registered for any class resource, i.e. interfaces, abstracts or normal classes.\n\n### Global Factories\n````php\n\u003c?php\n\n    $simpleClass = new SimpleClass();\n    $factory = function() use ($simpleClass) {\n        return new ExtendedClass($simpleClass);\n    };\n    \n    $creator-\u003eregisterFactory($factory, ExtendedClass::class);\n    \n    $extendedClass = $creator-\u003ecreate(ExtendedClass::class);\n    if ($extendedClass-\u003egetSimpleClass() === $simpleClass) {\n        echo 'Factories are awesome!';\n    }\n````\nThis comes in especially handy for stuff like database connections where you only want to create a connection if a component really depends on it.\n\n### Injected Factories\nOf course, you can also register a factory as injection:\n````php\n\u003c?php\n    $simpleClass = new SimpleClass();\n    $factory = function() use ($simpleClass) {\n        return new ExtendedClass($simpleClass);\n    };\n    \n    $extendedClass = $creator-\u003ecreateInjected(ExtendedClass:class)\n        -\u003ewithFactory($factory, ExtendedClass::class)\n        -\u003ecreate();\n    \n    if ($extendedClass-\u003egetSimpleClass() === $simpleClass) {\n        echo 'Factories are awesome!';\n    }\n````\nInjected factories overrule globally registered factories and even globally registered resources. However, they do not overrule injected resources. (Creation order routine is: Injected Instance -\u003e Injected Factory -\u003e Global Instance -\u003e Global Factory -\u003e Create Instance)\n\n### Self Factories\nTo avoid the need of a global factory, classes can also implement the `Creator\\Interfaces\\SelfFactory` interface.\nAll classes implementing this interface will not be built using their constructor; instead, they have to return a factory closure:\n\n```php\nclass MyDependency implements Creator\\Interfaces\\SelfFactory {\n\n    static function createSelf () : callable {\n        return function(AnotherDependency $a) : MyDependency {\n            return new static($a-\u003egetFoo());\n        }\n    }\n    \n    function __construct (Foo $foo) {\n        $this-\u003efoo = $foo;\n    }\n    \n}\n```\n\nIt is worth nothing here that not returning an instance of the class will throw an `InvalidFactoryResult` [exception](#exceptions).\n\n### Lazy Bound Factories\nIf you have factories that should not be created until they are required, you can register a lazy factory by using it's class name:\n\n````php\n\u003c?php\n\n    $creator-\u003eregisterFactory(SimpleFactory::class, SimpleClass::class);\n    \n    // Creates a SimpleClass with SimpleFactory\n    $simpleClass = $creator-\u003ecreate(SimpleClass::class);\n````\n\nAll lazy bound factories are stored to and read from the ResourceRegistry that defined them:\n````php\n\u003c?php\n\n    class SimpleFactory implements Factory {\n        \n        function __construct(SimpleClass $simpleClass) {\n            $this-\u003esimpleClass = $simpleClass;\n        }\n        \n        function createInstance() {\n            return $this-\u003esimpleClass;\n        }\n        \n    }\n\n    $creator-\u003eregisterFactory(SimpleFactory::class, SimpleClass::class);\n    \n    $simpleClass = new SimpleClass();\n    $simpleFactory = new SimpleFactory($simpleClass);\n    \n    $creator-\u003eregisterClassResource($simpleFactory);\n    \n    $generatedSimpleClass = $creator-\u003ecreate(SimpleClass::class);\n    if ($simpleClass === $generatedSimpleClass) {\n        echo 'Congratulations, this example is completely useless and works!';\n    }\n````\n\n### Factory Result Caching\nAll factory results are registered to their corresponding `ResourceRegistry`, i.e. a injected factory will store it's result to the injected registry and thereby make it's created resource available during this creation process only.\nThe only exception is a lazy bound factory with an injected dependency; in that case, the result of the factory is cached in the injection registry.\n\n````php\n\u003c?php\n\n    class ArbitraryFactory implements Factory {\n        \n        function __construct(SimpleClass $simpleClass) {\n            $this-\u003esimpleClass = $simpleClass;\n        }\n        \n        function createInstance() {\n            return $this-\u003esimpleClass;\n        }\n        \n    }\n\n    $creator-\u003eregisterFactory(ArbitraryFactory::class, ArbitraryClassWithSimpleClassDependency::class);\n    \n    $injectedArbitraryClass = $creator-\u003ecreateInjected(ArbitraryClassWithSimpleClassDependency::class)\n        -\u003ewith(new SimpleClass())\n        -\u003ecreate();\n    \n    $anyArbitraryClass = $creator-\u003ecreate(ArbitraryClassWithSimpleClassDependency::class);\n````\nIn the example above, the instances of `ArbitraryClassWithSimpleClassDependency` will not be the same. Creator detects that `SimpleClass` is a dependency of the registered factory and therefore create a new instance of `ArbitraryFactory` with the injected `SimpleClass`. This new factory instance is stored to the injected registry and will not affect other creations.\n\n## Uninstantiable Classes\n### Singletons\nSingletons can be resolved if they implement the `Creator\\Interfaces\\Singleton` interface.\n\n### Abstracts, Interfaces\nIf Creator stumbles upon an interface or an abstract class, it will try to look up the resource registry if any resource implements the interface / abstract class. First one is being served.\n\n## Registering Resources\n### Classes\nIf you want creator to use a certain instance of a class, you can register any object to Creator. It will then use this instance for any upcoming creation - a more \"persistent\" injection.\n````php\n\u003c?php\n    $a = new stdClass;\n    $a-\u003efoo = 'bar';\n    \n    $creator = new Creator\\Creator;\n    $creator-\u003eregisterClassResource($a);\n    \n    $instance = $creator-\u003ecreate('stdClass'); // you should not use hardcoded strings as class names; always prefer the class constant\n    echo $instance-\u003efoo; // bar\n````\nThe optional second parameter `$classResourceKey` of the method `registerClassResource` bypasses a get_class determination of the object. This might break code completion and type hinting, so use it wisely.\n### Primitive (scalar) Resources\nCreator supports registering scalar values by variable name.\n\n````php\n\u003c?php\n\n    class A {\n        function __construct($foo) {\n            echo $foo;\n        }\n    }\n    \n    $creator = new Creator\\Creator;\n    $creator-\u003ecreateInjected(A::class)\n        -\u003ewith('bar', 'foo') // first value is the injection, second the resource key\n        -\u003ecreate();\n````\n\nIn previous versions of Creator, there was a method to register primitive resources in the global registry.\nThis has been removed as it might cause unexpected behaviour and hinder future development.\n\nHowever, if you *really* need it (but don't say nobody told you it's a bad idea), you can still achieve this by registering the scalar value to a `ResourceRegistry` and pass this registry while constructing your `Creator\\Creator` instance. See the tests for example code.\n#### Primitive resource specifics\n- If an argument has a default value and Creator can not find a matching scalar value, it will use the default value.\n- Registering an object with `Creation::with()` will always result in a class resource registration, i.e. registering `$creation-\u003ewith($myInstance, 'foo');` will only register `$myInstance` as class foo, but never as primitive resource.\n\n## Exceptions\nAll exceptions derive from `Creator\\Exceptions\\CreatorException`. Use this class in your catch block to catch *all* Creator-related exceptions.\n\nAdditionally, there are more specific exceptions:\n* If Creator is unable to resolve a dependency, it will throw `Creator\\Exceptions\\Unresolvable`.\n* If you are registering a factory which is not a `callable` or an instance of / a class name of a class that implements `Creator\\Interfaces\\Factory`, it will throw `Creator\\Exceptions\\InvalidFactory`.\n* If a self-factory returns a class which is not an instance of self, it will throw `Creator\\Exceptions\\InvalidFactoryResult`.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffilecage%2Fcreator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffilecage%2Fcreator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffilecage%2Fcreator/lists"}