{"id":19374718,"url":"https://github.com/gyselroth/micro-container","last_synced_at":"2025-02-24T15:26:43.431Z","repository":{"id":62513841,"uuid":"111523094","full_name":"gyselroth/micro-container","owner":"gyselroth","description":"Lightweight dependency injection container for PHP","archived":false,"fork":false,"pushed_at":"2019-12-03T14:04:54.000Z","size":171,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-07T03:12:27.433Z","etag":null,"topics":["php-di"],"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/gyselroth.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-21T08:50:19.000Z","updated_at":"2022-08-29T06:09:56.000Z","dependencies_parsed_at":"2022-11-02T12:48:41.421Z","dependency_job_id":null,"html_url":"https://github.com/gyselroth/micro-container","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyselroth%2Fmicro-container","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyselroth%2Fmicro-container/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyselroth%2Fmicro-container/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyselroth%2Fmicro-container/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gyselroth","download_url":"https://codeload.github.com/gyselroth/micro-container/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240502424,"owners_count":19811802,"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":["php-di"],"created_at":"2024-11-10T08:35:57.833Z","updated_at":"2025-02-24T15:26:43.406Z","avatar_url":"https://github.com/gyselroth.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dependency Injection Container\n[![Build Status](https://travis-ci.org/gyselroth/micro-container.svg?branch=master)](https://travis-ci.org/gyselroth/micro-container)\n[![Code Coverage](https://scrutinizer-ci.com/g/gyselroth/micro-container/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/gyselroth/micro-container/?branch=master)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/gyselroth/micro-container/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/gyselroth/micro-container/?branch=master)\n[![Latest Stable Version](https://img.shields.io/packagist/v/gyselroth/micro-container.svg)](https://packagist.org/packages/gyselroth/micro-container)\n[![GitHub release](https://img.shields.io/github/release/gyselroth/micro-container.svg)](https://github.com/gyselroth/micro-container/releases)\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/gyselroth/micro-container/master/LICENSE)\n\nThis is a lightweight dependency injection container for PHP 7.1+.\nIt supports full autowiring and lets you configure the container with whatever configuration format you want.\nSince it is written to be lightweight and does build everything on the fly (No worries reflection is cached by PHP itself) it is super easy to use and still very fast. Despite the fact of being lightweight it still offers enough features to use it in a major project.\n\n# Table of Contents\n  * [Description](#description)\n  * [Features](#features)\n  * [Requirements](#requirements)\n  * [Download](#download)\n  * [Changelog](#changelog)\n  * [Contribute](#contribute)\n  * [Documentation](#documentation)\n    * [Configuration](#configuration)\n    * [Retrieving services](#retrieving-services)\n    * [Autowiring](#autowiring)\n    * [Constructor injection](#constructor-injection)\n    * [Setter injection](#setter-injection)\n    * [Reference to other services](#reference-to-other-services)\n    * [Using Interfaces, abstract/parent classes or aliases](#using-interfaces-abstractparent-classes-or-aliases)\n    * [Values and environment variables](#values-and-environment-variables)\n    * [Singletons](#singletons)\n    * [Factories](#factories)\n    * [Lazy services](#lazy-services)\n    * [Lazy services wrapped in callbacks](#lazy-services-wrapped-in-callbacks)\n    * [Exposing and nesting services](#exposing-and-nesting-services)\n    * [Configuring services via parent classes or interfaces](#configuring-services-via-parent-classes-or-interfaces)\n    * [Using method result as service](#using-method-result-as-service)\n    * [Make at runtime](#make-at-runtime)\n\n## Features\n\n* PSR-11 compatible DIC\n* Full inbuilt autowiring\n* Configurable via native php array (or anything else decoded into an array)\n* Setter/Constructor injection\n* Environment variables\n* Lazy loading/Callback wrapping\n* Singletons\n* Factories\n* Configuration of multiple services via interface/parent class declarations\n* Supports parent container\n\n## Requirements\nThe library is only \u003e= PHP 7.1 compatible.\n\n## Download\nThe package is available at packagist: https://packagist.org/packages/gyselroth/micro-container\n\nTo install the package via composer execute:\n```\ncomposer require gyselroth/micro-container\n```\n\n## Changelog\nA changelog is available [here](https://github.com/gyselroth/micro-container/blob/master/CHANGELOG.md).\n\n## Contribute\nWe are glad that you would like to contribute to this project. Please follow the given [terms](https://github.com/gyselroth/micro-container/blob/master/CONTRIBUTING.md).\n\n## Documentation\nWe all know how a DIC must work so we go directly to a example how to use it with a common dependency such as \na [Monolog](https://github.com/Seldaek/monolog) logger.\n\n```php\nuse Micro\\Container\\Container; \nuse Psr\\Log\\LoggerInterface;\nuse Monolog\\Logger;\nuse Monolog\\Handler\\StreamHandler;\nuse Monolog\\Formatter\\FormatterInterface;\nuse Monolog\\Formatter\\LineFormatter;\n\n$config = [\n    LoggerInterface::class =\u003e [\n        'use' =\u003e Logger::class,\n        'calls' =\u003e [\n            StreamHandler::class =\u003e [\n                'method' =\u003e 'pushHandler',\n                'arguments' =\u003e ['handler' =\u003e '{'.StreamHandler::class.'}']\n            ],\n        ],\n        'services' =\u003e [\n            StreamHandler::class =\u003e [\n                'arguments' =\u003e [\n                    'stream' =\u003e '{ENV(LOG_FOLDER),/tmp}/my_app.log',\n                    'level' =\u003e 100\n                ]\n                'calls' =\u003e [\n                    FormatterInterface::class =\u003e [\n                        'method' =\u003e 'setFormatter'\n                    ]\n                ]\n            ]\n        ]\n    ],\n    FormatterInterface::class =\u003e [\n        'use' =\u003e LineFormatter::class,\n        'arguments' =\u003e [\n            'dateFormat' =\u003e \"Y-d-m H:i:s\",\n            'format' =\u003e \"%datetime% [%context.category%,%level_name%]: %message% %context.params% %context.exception%\\n\"\n        ]\n    ]\n];\n\n$container = new Container($config);\n$-\u003eget(LoggerInterface::class)-\u003einfo('Hello world');\n```\n\n### Configuration\nThe container only accepts one argument and this is a configuration. \nHuge advantage is, that you can use anything you would like to configure your container.\nYou can configure it directly via PHP like the example above or use a configuration file or even a configuration library such as [Noodlehaus\\Config](https://github.com/hassankhan/config).\n\nHere is the same config but in YAML:\n```yaml\nMonolog\\Formatter\\FormatterInterface:\n  use: Monolog\\Formatter\\LineFormatter\n  arguments:\n    dateFormat: \"Y-d-m H:i:s\"\n    format: \"%datetime% [%context.category%,%level_name%]: %message% %context.params% %context.exception%\\n\"\nPsr\\Log\\LoggerInterface:\n  use: \"Monolog\\\\Logger\"\n  arguments:\n    name: default\n  calls:\n    Monolog\\Handler\\StreamHandler:\n      method: pushHandler\n      arguments:\n        handler: '{Monolog\\Handler\\StreamHandler}'\n  services:\n    Monolog\\Handler\\StreamHandler:\n      use: \\Monolog\\Handler\\StreamHandler\n      arguments:\n        stream: '{ENV(LOG_FOLDER,/tmp)}/my_app.log'\n        level: 100\n      calls:\n        formatter:\n          method: setFormatter\n```\n\nUsing (for example [Noodlehaus\\Config](https://github.com/hassankhan/config)) would result in:\n\n```php\nuse Noodlehaus\\Config;\nuse Micro\\Container\\Container;\n\n$path = __DIR__.DIRECTORY_SEPARATOR.'*.yaml';\n$config = new Config($path);\n$container = new Container($config);\n```\n\n## Retrieving services\nRetrieve as service from the container is an easy task, let us\nrequest the logger:\n\n```php\n$container = new Container();\n$container-\u003eget(LoggerInterface::class)-\u003einfo('Hello world');\n```\n\n### Autowiring\nThis container does autowiring by default. You do not need to configure anything for it.\nAlso it is not required that you configure a service explicitly which is requested by a dependency. \nIf it is not configured but can be resolved anyway you're good to go.\nThe container tries to resolve everything possible automatically. You only need to configure what is really required.\n\n### Constructor injection\nYou can pass constructor arguments via the keyword `arguments`.\n\n\u003e **Attention**: The container is based on named arguments.\nOrder does not matter but you need to name the arguments as they are defined in the constructor of a class itself.\n\nExample:\n```php\n$config = [\n    MongoDB\\Client::class =\u003e [\n        'arguments' =\u003e [\n            'uri' =\u003e 'mongodb://localhost:27017',\n            'driverOptions' =\u003e [\n                'typeMap' =\u003e [\n                    'root' =\u003e 'array',\n                    'document' =\u003e 'array',\n                    'array' =\u003e 'array',\n                ]\n            ]\n        ],\n    ],\n]\n```\n\n### Setter injection\nSetter inection is done via `calls`. Again arguments must be named. Ordering doesn't matter. The container tries to resolve all arguments where it can be done\nautomatically. \n`calls` requires an array with setter calls. The name of a call like in this example `StreamHandler::class` does not matter, \nit is only named that it can easily overwritten by other configuration files/array.\nOne setter requires a `method` and optionally an array of `arguments`.\nAgain the container works with named arguments. If StreamHandler::pushHandler() has an argument named 'handler' you have to name it 'handler', order does not matter.\n\n```php\n'calls' =\u003e [\n   StreamHandler::class =\u003e [\n        'method' =\u003e 'pushHandler',\n        'arguments' =\u003e ['handler' =\u003e '{'.StreamHandler::class.'}']\n   ],\n]\n```\n\nThe same goes with an unnamed call:\n```php\n'calls' =\u003e [\n   [\n        'method' =\u003e 'pushHandler',\n        'arguments' =\u003e ['handler' =\u003e '{'.StreamHandler::class.'}']\n   ],\n]\n```\n\nExample:\n```php\n$config = [\n    LoggerInterface::class =\u003e [\n        'use' =\u003e Logger::class,\n        'calls' =\u003e [\n            StreamHandler::class =\u003e [\n                'method' =\u003e 'pushHandler',\n                'arguments' =\u003e ['handler' =\u003e '{'.StreamHandler::class.'}']\n            ],\n        ],\n        'services' =\u003e [\n            StreamHandler::class =\u003e [\n                'arguments' =\u003e [\n                    'stream' =\u003e 'my_file.log',\n                    'level' =\u003e 100\n                ]\n            ]\n        ]\n    ],\n];\n```\n\n#### Batching multiple calls\n\nIf a lot of calls need to be made with the same pattern, there is a possibility to use `batch` which allows\nto define a method signature using `arguments` and list all calls in `batch`:\n\nExample:\n```php\nRouteCollector::class =\u003e [\n    'calls' =\u003e [[\n        'method' =\u003e 'addRoute',\n        'arguments' =\u003e [\n            'httpMethod',\n            'route',\n            'handler',\n        ],\n        'batch' =\u003e [\n            ['GET', '/api/v2', [Specifications::class, 'getApi']],\n            ['GET', '/api/v2/users', [v2\\Users::class, 'getAll']],\n            ['GET', '/api/v2/users/{user}', [v2\\Users::class, 'getOne']],\n            ['POST', '/api/v2/users', [v2\\Users::class, 'post']],\n            ['PUT', '/api/v2/users/{user}', [v2\\Users::class, 'put']],\n            ['PATCH', '/api/v2/users/{users}', [v2\\Users::class, 'patch']],\n            ['DELETE', '/api/v2/users/{user}', [v2\\Users::class, 'delete']],\n        ]\n    ]\n]\n```\n\n### Reference to other services\nIf you want to pass another service you can wrap your value into `{service name}`. This will let the container to search for a service called 'service name'.\n\n### Using Interfaces, abstract/parent classes or aliases\nA service named with an interface name like `Psr\\Log\\LoggerInterface` can be configured to use specific implementation like `Monolog\\Logger` via the \nkeyword `use`.\n\nExample:\n```php\n$config = [\n    LoggerInterface::class =\u003e [\n        'use' =\u003e Logger::class,\n    ]\n];\n```\nThis will configure the dic to return an instance of Logger::class if an implementation of LoggerInteface::class is required.\n\n\n### Values and environment variables\nPassing values work like passing service references. The only difference is that static values must not be wrapped in `{}`.\nIt is also possible to read values from environment variables. This can be done like `{ENV(LOG_FOLDER)}` or with an optional default\nvalue `{ENV(LOG_FOLDER,/tmp)}`. If the variable is found it will use the value of `LOG_FOLDER` otherwise the default value. If no default value is given and the env variable was not found an exception `Micro\\Container\\Exception\\EnvVariableNotFound` will be thrown.\n\nExample:\n```php\n$config = [\n    LoggerInterface::class =\u003e [\n        'use' =\u003e Logger::class,\n        'calls' =\u003e [\n            StreamHandler::class =\u003e [\n                'method' =\u003e 'pushHandler',\n                'arguments' =\u003e ['handler' =\u003e '{'.StreamHandler::class.'}']\n            ],\n        ],\n        'services' =\u003e [\n            StreamHandler::class =\u003e [\n                'arguments' =\u003e [\n                    'stream' =\u003e '{ENV(LOG_FOLDER),logs}/my_file.log',\n                    'level' =\u003e 100\n                ]\n            ]\n        ]\n    ],\n];\n```\n\n### Singletons\nA service is by default a singleton. If a service once is created it will be used if another service requires the same dependency.\nThis behaviour might be changed to `singleton: false` which will always resolve the requested service.\n\nExample:\n```php\n$config = [\n    SmtpTransport::class =\u003e [\n        'arguments' =\u003e [\n            'server' =\u003e '127.0.0.1'\n        ],\n        'singleton' =\u003e false\n    ]\n];\n\n$container = new Container($config);\n$a = $container-\u003eget(SmtpTransport::class);\n$b = $container-\u003eget(SmtpTransport::class);\n```\n\n`$a` and `$b` are different instances now. \n\n### Factories\nFactories are usually static methods which return an instance of a class while only the factory knows how to construct such an object.\n\nExample:\n```php\n$config = [\n    SmtpTransport::class =\u003e [\n        'use' =\u003e SmtpTransportFactory::class,\n        'factory' =\u003e 'factory_method'\n        'arguments' =\u003e [\n            'server' =\u003e '127.0.0.1'\n        ]\n    ]\n];\n\n$container = new Container($config);\n$transport = $container-\u003eget(SmtpTransport::class);\n```\n### Lazy services\nLazy services are great if you have very complex objects or just many of them. A service declared as `lazy` will be return as\na proxy object and as soon as it is really required it gets initialized. Proxy objects are implemented trough [Ocramius/ProxyManager](https://github.com/Ocramius/ProxyManager).\n\nLet's say there is a PDO service and it is required by lots of other services and it does already connect to the database server within the constructor.\nThis is fine but may be not usable if you only rely on the connection at certain points in your app. \nBy declaring it as a lazy service, a proxy object of PDO gets injected into your classes which require a PDO service and as soon as your\nclass access the PDO service it gets created as real object.\n\nExample:\n```php\n$config = [\n    PDO::class =\u003e [\n        'arguments' =\u003e [\n            'dsn' =\u003e 'mysql:127.0.0.1'\n        ],\n        'lazy' =\u003e true\n    ]\n];\n```\nBe careful with lazy services. Only use it if it makes sense.\n\n### Lazy services wrapped in callbacks\nAnother way to achieve lazy services is to wrap them in a callback. The service only gets resolved if the callback gets executed.\nWhile `lazy` will return an exact copy (proxy) instance of the service, `wrap` will return a closure `function(){return $service;}` whereas $service gets resolved as soon as the callback gets executed.\n\nExample:\n```php\n$config = [\n    PDO::class =\u003e [\n        'arguments' =\u003e [\n            'dsn' =\u003e 'mysql:127.0.0.1'\n        ],\n        'wrap' =\u003e true\n    ]\n];\n\n$container = new Container($config);\n//Note: PDO::class is only resolved to a callback now, there is no actual instance yet.\n$pdo_callback = $container-\u003eget(PDO::class);\n\n//create instance\n$pdo = $pdo_callback();\n```\n\n### Exposing and nesting services\nServices configured at the top level of the configuration are exposed by default. You can nest services via `services` to hide services within the container.\nThis leads to a cleaner and more readable configuration. Given the Monolog example the services `Monolog\\Formatter\\FormatterInterface` and `Psr\\Log\\LoggerInterface` are configured at the top level.\nTherefore those can be requested directly from the container whereas `Monolog\\Handler\\StreamHandler` is a sub service of `Psr\\Log\\LoggerInterface` and can not be requested.\nThe container tries to look up services from the bottom to the top. If there is service configured with the name the container is looking for it takes that configuration and injects the service at this level.\nIf no service is found the container will look a level above and so on.\nYou can nest service as deep as you want.\n\nExample:\n```php\n$config = [\n    LoggerInterface::class =\u003e [\n        'use' =\u003e Logger::class,\n        'calls' =\u003e [\n            StreamHandler::class =\u003e [\n                'method' =\u003e 'pushHandler',\n                'arguments' =\u003e ['handler' =\u003e '{'.StreamHandler::class.'}']\n            ],\n        ],\n        'services' =\u003e [\n            StreamHandler::class =\u003e [\n                'arguments' =\u003e [\n                    'stream' =\u003e '/my_file.log',\n                    'level' =\u003e 100\n                ]\n            ]\n        ]\n    ],\n];\n```\n\nIn the above example the service `StreamHandler::class` is a sub service of `LoggerInterface::class` and can not be requested directly from the container.\n\n### Configuring services via parent classes or interfaces\nIt is also possible to configure services of the same type with one declaration.\nOf the same type means what parent classes or interfaces a certain class implements.\nAll service declarations get merged during requesting a service.\n\nExample:\n```php\n$config = [\n    JobInterface::class =\u003e [\n        'arguments' =\u003e [\n            'bar' =\u003e 'foo'\n        ],\n        'singleton' =\u003e true\n    ],\n    Job\\C::class =\u003e [\n        'arguments' =\u003e [\n            'bar' =\u003e 'bar'\n        ]\n    ]\n];\n\n$container = new Container($config);\n$a = $container-\u003eget(Job\\A::class);\n$b = $container-\u003eget(Job\\B::class);\n$c = $container-\u003eget(Job\\C::class);\n```\n\nAll implementations of `JobInterface::class` are now singletons and have a constructor argument `bar` set to foo\nexpect `Job\\C::class` which is also a singleton but the constructor argument `bar` is set too bar.\n\nThis also works for nested services and the whole sub service tree get merged with declarations of the same type.\nFor example a sub service checks parent service declarations of the same and will merge those.\n\nLet's say we have a job manager and a job class which implements the interface JobInterface:\n\nExample:\n```php\n$config = [\n    JobInterface::class =\u003e [\n        'arguments' =\u003e [\n            'bar' =\u003e 'foo'\n        ],\n    ],\n    JobManager::class =\u003e [\n        'arguments' =\u003e [\n            'bar' =\u003e 'bar'\n        ],\n        'calls' =\u003e [\n            [\n                'method' =\u003e 'injectJob',\n                'arguments' =\u003e ['job' =\u003e '{my_job}']\n            ],\n        ],\n        'services' =\u003e [\n            'my_job' =\u003e [\n                'use' =\u003e Job::class\n            ]\n        ]\n    ]\n];\n\n$container = new Container($config);\n$container-\u003eget(JobManager::class);\n```\n\nThe job `my_job` will get injected into the job manager with the constructor argument `bar =\u003e foo` since\nwe declared a common service configuration for `JobInterface::class`.\nYou may also declare JobInterface::class on the same nesting level as the job itself or as a child service.\n\nIf you do not want that a service looks for parent services of the same type and tries to merge the service configuration you \ncan disable this feature by setting `merge` to `false` on the given service.\n\n\n### Using method result as service\nIt is possible to define a service which does use the result of a method call of another service. Have a look at this example where we use the [MongoDB library](https://github.com/mongodb/mongo-php-library) and\nfrom it an instance of `MongoDB\\Database` but this instance must be created from `MongoDB\\Client`.\n```php\n$config = [\n    MongoDB\\Client::class =\u003e [\n        'arguments' =\u003e [\n            'uri' =\u003e 'mongodb://localhost:27017',\n            'driverOptions' =\u003e [\n                'typeMap' =\u003e [\n                    'root' =\u003e 'array',\n                    'document' =\u003e 'array',\n                    'array' =\u003e 'array',\n                ]\n            ]\n        ],\n    ],\n    MongoDB\\Database::class =\u003e [\n        'use' =\u003e '{MongoDB\\Client}',\n        'calls' =\u003e [[\n            'method' =\u003e 'selectDatabase',\n            'arguments' =\u003e [\n                'databaseName' =\u003e 'my_database'\n            ],\n            'select' =\u003e true\n        ]]\n    ]\n]\n```\nInstead setting a specific class in the `use` statement you can wrap another service in `{}` to use that service as a parent service.\nThe service `MongoDB\\Database` is now actually an instance of `MongoDB\\Client`. \nWe can declare a calls statement with the option `select` to `true`, this will tell the container, that we want to use the result of `selectDatabase`.\n\n\u003e**Note**: `calls` supports chaining of multiple method calls. You may also mix select=true/false methods but keep in mind that the order matters! All calls will get executed in the configured order.\n\nThis example will build an [elasticsearch client](https://github.com/elastic/elasticsearch-php) using first a factory and on the factory result a `setHosts` call gets executed and from that a `build` call gets executed whereas we use the result of as value for\nthe server `Elasticsearch\\Elasticsearch\\Client::class`.\n\n```php\n$config = [\n    Elasticsearch\\Elasticsearch\\Client::class =\u003e [\n        'use' =\u003e Elasticsearch\\Elasticsearch\\ClientBuilder::class,\n        'factory' =\u003e 'create',\n        'calls' =\u003e [\n            [\n                'method' =\u003e 'setHosts',\n                'arguments' =\u003e ['hosts' =\u003e [\"http://localhost:9200\"]]\n            ],\n            [\n                'method' =\u003e 'build',\n                'select' =\u003e true,\n            ]\n        ],\n    ],\n]\n```\n\n\u003e**Note**: The usage of the `selects` statement besides `calls` is deprecated as of v2.0.2 and gets removed in v3.0.0. The only supported option beginning with v3.0.0 is the `select` statement within `calls`.\n\n### Make at runtime\n\nBesides static configuration of the service tree, Micro\\Container also allows to build instances at runtime. This is especially useful if \nservice constructors need arguments which are only ever known at runtime.\n\n\u003e**Note**: `make()` is not compatible with PSR-11.\n\n```php\n$service = $container-\u003emake(JobInterface::class, [\n    'arg1' =\u003e 'myvalue'\n]);\n\nLike everthing else, the parameters array excepts an array with named parameters to build the service. It is certainly possible \nto combine arguments at runtime and statically configured arguments within the dic configuration.\n\n\u003e**Note**: Dynamically created instances with `make()` are always `singleton: false`.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgyselroth%2Fmicro-container","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgyselroth%2Fmicro-container","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgyselroth%2Fmicro-container/lists"}