{"id":15525362,"url":"https://github.com/ghostwriter/container","last_synced_at":"2025-04-23T08:49:44.928Z","repository":{"id":37104735,"uuid":"431529446","full_name":"ghostwriter/container","owner":"ghostwriter","description":"Provides a Dependency Injection Service Container for PHP","archived":false,"fork":false,"pushed_at":"2025-04-22T00:46:38.000Z","size":1615,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"5.0.x","last_synced_at":"2025-04-22T01:29:32.496Z","etag":null,"topics":["container","dependency-injection","ghostwriter","php","psr-11","service-container"],"latest_commit_sha":null,"homepage":"https://github.com/ghostwriter/container","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ghostwriter.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["ghostwriter"]}},"created_at":"2021-11-24T15:09:35.000Z","updated_at":"2025-04-22T00:46:41.000Z","dependencies_parsed_at":"2024-01-29T09:53:09.013Z","dependency_job_id":"d6196ad6-2e9a-4f1d-9d33-fe6210d57e09","html_url":"https://github.com/ghostwriter/container","commit_stats":{"total_commits":282,"total_committers":1,"mean_commits":282.0,"dds":0.0,"last_synced_commit":"d70885001220497f90726daa1af7a3a396e74e21"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostwriter%2Fcontainer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostwriter%2Fcontainer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostwriter%2Fcontainer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostwriter%2Fcontainer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ghostwriter","download_url":"https://codeload.github.com/ghostwriter/container/tar.gz/refs/heads/5.0.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250402895,"owners_count":21424770,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["container","dependency-injection","ghostwriter","php","psr-11","service-container"],"created_at":"2024-10-02T10:57:05.019Z","updated_at":"2025-04-23T08:49:44.922Z","avatar_url":"https://github.com/ghostwriter.png","language":"PHP","readme":"# Container\n\n[![GitHub Sponsors](https://img.shields.io/github/sponsors/ghostwriter?label=Sponsor+@ghostwriter/container\u0026logo=GitHub+Sponsors)](https://github.com/sponsors/ghostwriter)\n[![Automation](https://github.com/ghostwriter/container/actions/workflows/automation.yml/badge.svg)](https://github.com/ghostwriter/container/actions/workflows/automation.yml)\n[![Supported PHP Version](https://badgen.net/packagist/php/ghostwriter/container?color=8892bf)](https://www.php.net/supported-versions)\n[![Downloads](https://badgen.net/packagist/dt/ghostwriter/container?color=blue)](https://packagist.org/packages/ghostwriter/container)\n\nProvides an extensible Dependency Injection Service Container for Automated Object Composition, Interception, and Lifetime Management.\n\n## Installation\n\nYou can install the package via composer:\n\n``` bash\ncomposer require ghostwriter/container\n```\n\n## Usage\n\n### Simple usage\n\nRegistering a service on the given container.\n\n```php\nfinal readonly class Service\n{\n    public function __construct(\n        private Dependency $dependency\n    ) {}\n\n    public function dependency():Dependency\n    {\n        return $this-\u003edependency;\n    }\n}\n\n$container = Container::getInstance();\n$service = $container-\u003eget(Service::class);\n\nassert($service instanceof Service); // true\nassert($service-\u003edependency() instanceof Dependency); // true\n```\n\n### Attributes\n\nRegistering services using attributes.\n\n#### `#[Inject]`\n\nRegistering a service on the container using attributes.\n\n```php\nuse Ghostwriter\\Container\\Attribute\\Inject;\n\nfinal readonly class Service\n{\n    public function __construct(\n        #[Inject(Dependency::class)]\n        private DependencyInterface $dependency\n    ) {}\n\n    public function dependency():Dependency\n    {\n        return $this-\u003edependency;\n    }\n}\n\n// when \"Service::class\" asks for \"DependencyInterface::class\" inject an instance of \"Dependency::class\"\n\n// the above is equivalent to the following\n// $container-\u003ebind(Service::class, DependencyInterface::class, Dependency::class);\n```\n\n---\n\nRegistering a service factory on the container using attributes.\n\n#### `#[Factory]`\n\n```php\nuse Ghostwriter\\Container\\Attribute\\Factory;\n\n#[Factory(ServiceFactory::class)]\nfinal readonly class Service\n{\n    public function __construct(\n        private Dependency $dependency\n    ) {}\n\n    public function dependency():Dependency\n    {\n        return $this-\u003edependency;\n    }\n}\n// the above is equivalent to the following\n// $container-\u003efactory(Service::class, ServiceFactory::class);\n```\n\n---\n\n#### `#[Extension]`\n\nRegistering a service extension on the container using attributes.\n\n```php\nuse Ghostwriter\\Container\\Attribute\\Extension;\n\n#[Extension(ServiceExtension::class)]\nfinal readonly class Service\n{\n    public function __construct(\n        private Dependency $dependency\n    ) {}\n\n    public function dependency():Dependency\n    {\n        return $this-\u003edependency;\n    }\n}\n// the above is equivalent to the following\n// $container-\u003eextend(Service::class, ServiceExtension::class);\n```\n\n---\n\n#### `#[Provider]`\n\nRegistering a service provider on the container using attributes.\n\n```php\nuse Ghostwriter\\Container\\Attribute\\Provider;\n\n#[Provider(ServiceProvider::class)]\nfinal readonly class Service\n{\n    public function __construct(\n        private DependencyInterface $dependency\n    ) {}\n\n    public function dependency():DependencyInterface\n    {\n        return $this-\u003edependency;\n    }\n}\n\n// the above is equivalent to the following\n// $container-\u003eprovide(ServiceProvider::class);\n```\n\n### Service Providers\n\nRegistering a service provider on the container.\n\n```php\ninterface TaskInterface {}\n\nfinal readonly class Task implements TaskInterface {}\n\nfinal class Tasks\n{\n    private array $tasks = [];\n    public function addTask(TaskInterface $task)\n    {\n        $this-\u003etasks[] = $task;\n    }\n}\n\nfinal readonly class TasksServiceProvider implements ServiceProviderInterface\n{\n    public function __invoke(ContainerInterface $container)\n    {\n        $container-\u003ealias(Task::class, TaskInterface::class);\n        \n        // \"set\" the service instance\n        $container-\u003eset(FirstTask::class, new FirstTask(), [Task::class]);\n        \n        // \"define\" the service builder\n        $container-\u003edefine(Tasks::class, static function (Container $container) {\n            /** @var Tasks $tasks */\n            $tasks = $container-\u003ebuild(Tasks::class);\n\n            foreach ($container-\u003etagged(Task::class) as $service) {\n                $tasks-\u003eaddTask($service);\n            }\n\n            return $tasks;\n        }, [Tasks::class, 'tasks']);\n        \n    }\n}\n\n$container-\u003eprovide(TasksServiceProvider::class);\n\n$service = $container-\u003eget(TaskInterface::class);\n\nassert($service instanceof Task); // true\n```\n\n### Contextual Bindings\n\nRegistering a Contextual Bindings on the container.\n\n```php\ninterface ClientInterface {}\n\nfinal readonly class RestClient implements ClientInterface {}\n\nfinal readonly class GraphQLClient implements ClientInterface {}\n\nfinal readonly class GitHub\n{\n    public function __construct(\n        private ClientInterface $client\n    ) {\n    }\n    public function getClient(): ClientInterface\n    {\n        return $this-\u003eclient;\n    }\n}\n\n// When GitHub::class asks for ClientInterface::class, it would receive an instance of GraphQLClient::class.\n$container-\u003ebind(GitHub::class, ClientInterface::class, GraphQLClient::class);\n\n// When any other service asks for ClientInterface::class, it would receive an instance of RestClient::class.\n$container-\u003ealias(ClientInterface::class, RestClient::class);\n```\n\n### Service Extensions\n\nRegistering a service extension on the container.\n\n```php\n/**\n * @implements ExtensionInterface\u003cGitHubClient\u003e\n */\nfinal readonly class GitHubExtension implements ExtensionInterface\n{\n    /**\n     * @param GitHubClient $service\n     * @return GitHubClient\n     */\n    public function __invoke(ContainerInterface $container, object $service): object\n    {\n        $service-\u003esetEnterpriseUrl(\n            $container-\u003eget(GitHubClient::GITHUB_HOST)\n        );\n\n        return $service;\n    }\n}\n\n$container-\u003ealias(GitHubClientInterface::class, GitHubClient::class);\n$container-\u003eextend(GitHubClientInterface::class, GitHubExtention::class);\n```\n\n### Service Factory\n\nRegistering a service factory on the container.\n\n```php\nfinal readonly class Dependency {}\nfinal readonly class Service\n{\n    public function __construct(\n        private Dependency $dependency\n    ){}\n\n    public function dependency():Dependency\n    {\n        return $this-\u003edependency;\n    }\n}\nfinal readonly class ServiceFactory {\n  public function __invoke(Container $container): Service\n  {\n     return new Service($container-\u003eget(Dependency::class));\n  }\n}\n\n$container = Container::getInstance();\n\n$container-\u003efactory(Service::class, ServiceFactory::class);\n\n$service = $container-\u003eget(Service::class);\n\nassert($service instanceof Service); // true\nassert($service-\u003edependency() instanceof Dependency); // true\n```\n\n### Testing\n\n``` bash\ncomposer test\n```\n\n### Changelog\n\nPlease see [CHANGELOG.md](./CHANGELOG.md) for more information what has changed recently.\n\n### Security\n\nIf you discover any security related issues, please email `nathanael.esayeas@protonmail.com` instead of using the issue tracker.\n\n## Sponsors\n\n[[`Become a GitHub Sponsor`](https://github.com/sponsors/ghostwriter)]\n\n## Credits\n\n- [Nathanael Esayeas](https://github.com/ghostwriter)\n- [All Contributors](https://github.com/ghostwriter/container/contributors)\n\n## License\n\nThe BSD-4-Clause. Please see [License File](./LICENSE) for more information.\n","funding_links":["https://github.com/sponsors/ghostwriter"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghostwriter%2Fcontainer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fghostwriter%2Fcontainer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghostwriter%2Fcontainer/lists"}