> For the complete documentation index, see [llms.txt](https://quantumphp.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://quantumphp.gitbook.io/docs/packages/di/usage.md).

# Usage

This package gives you two main workflows:

* register a binding and resolve a shared instance with `get()`
* create a fresh object graph on demand with `create()` or `autowire()`

## Register an interface binding

Use `register()` when application code depends on an interface or abstract class name.

```php
use App\Contracts\MailerInterface;
use App\Services\SmtpMailer;
use Quantum\Di\Di;

Di::register(SmtpMailer::class, MailerInterface::class);

$mailer = Di::get(MailerInterface::class);
```

`get()` returns the same shared instance on later calls for `MailerInterface::class`.

## Create a class without pre-registration

Use `create()` when you want a fresh instance and do not need shared caching.

```php
use App\Services\ReportBuilder;
use Quantum\Di\Di;

$builderA = Di::create(ReportBuilder::class);
$builderB = Di::create(ReportBuilder::class);
```

`$builderA` and `$builderB` are different objects.

Because `create()` auto-registers missing classes against themselves, this works even when `ReportBuilder` was not registered earlier. That self-registration persists in the container registry, so a later `Di::get(ReportBuilder::class)` call will succeed and start returning a shared instance for that class key.

## Seed a prebuilt instance

Use `set()` when you already have an object and want the container to return it later.

```php
use App\Contracts\ClockInterface;
use App\Testing\FakeClock;
use Quantum\Di\Di;

Di::set(ClockInterface::class, new FakeClock());

$clock = Di::get(ClockInterface::class);
```

The current implementation has two gotchas:

* you cannot call `set()` twice for the same abstract once an instance already exists
* the abstract key must be a real class or interface name

Also, `set()` seeds only the runtime container entry. If you clear the container with `Di::resetContainer()`, the seeded object is removed and future `get()` calls fall back to the registered concrete binding.

## Autowire a callable

`autowire()` prepares the arguments for a closure or array callable.

```php
use App\Contracts\MailerInterface;
use Quantum\Di\Di;

$args = Di::autowire(
    function (MailerInterface $mailer, string $subject = 'Hello') {
        return [$mailer, $subject];
    },
    ['Weekly digest']
);
```

The returned `$args` array contains the resolved mailer instance plus the manual subject argument.

You still invoke the callable yourself:

```php
$result = (function (MailerInterface $mailer, string $subject = 'Hello') {
    return [$mailer, $subject];
})(...$args);
```

If you pass a class-string array callable such as `[Handler::class, 'run']`, `autowire()` only reflects the method signature. It does not create a `Handler` instance or perform the method call for you.

## Understand argument precedence

Constructor and callable parameters are resolved in a strict order.

### Registered services come first

If a parameter type is registered in the container, that dependency is injected before any manual argument is consumed.

### Instantiable classes come next

If the type is not registered but names an instantiable class, the container creates it automatically.

### Scalar values are positional

For non-class parameters, manual `$args` are consumed with `array_shift()`.

```php
$args = Di::autowire(
    function (string $name, int $count) {},
    ['cache', 3]
);
```

The resolver does not match by parameter name.

### Array parameters capture the remaining args

If a parameter is typed as `array`, it receives the full remaining manual argument list.

```php
$args = Di::autowire(
    function (array $payload) {},
    ['a' => 1, 'b' => 2]
);
```

In the current implementation, `$payload` becomes the remaining `$args` array exactly as held by the resolver.

## Handle circular dependencies early

If class graphs reference each other in a loop, resolution fails with `DiException::circularDependency(...)`.

Example shape:

* `A` depends on `B`
* `B` depends on `A`

The exception message includes the chain that was being resolved.

## Reset state in tests or isolated runs

Use:

* `Di::resetContainer()` to clear shared instances but keep bindings
* `Di::reset()` to clear both bindings and shared instances

`reset()` is the stronger reset and is usually the safer option for test isolation.

## Caveats

* `get()` fails for unknown abstractions; it does not auto-register them.
* `autowire()` does not accept string callables or invokable objects.
* Missing required scalar parameters can fall through as `null` and fail later when PHP enforces the signature.
* Shared instances are container-scoped. If the app context changes containers, later `Di::...` calls follow the new container.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://quantumphp.gitbook.io/docs/packages/di/usage.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
