Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[12.x] Container currentlyResolving utility #55684

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

jrseliga
Copy link
Contributor

@jrseliga jrseliga commented May 8, 2025

Exposing what the container is currently resolving would be a useful feature.

For example, given a server:

class Production
{
    protected array $features;

    public function __construct(array $features)
    {
        $this->features = $features;
    }
}

And a repository that holds registrations mapping a server to features:

class Registrar
{
    protected array $registrations = [
        Staging::class => [
            Nginx::class,
            Php::class,
        ],
        Production::class => [
            Caddy::class,
            Php::class,
        ],
    ];

    public function for(string $server): array
    {
        return $this->registrations[$server]
    }
}

We could have a Contextual Attribute responsible for returning the features registered specifically to a server instead of having to perform an operation on our Registrar

class Production
{
    protected array $features;

    public function __construct(#[RegisteredFor] array $features)
    {
        $this->features = $features;
    }
}

This PR provides access to what the container is currently resolving -- allowing:

#[Attribute(Attribute::TARGET_PARAMETER)]
class RegisteredFor implements ContextualAttribute
{
    public static function resolve(self $attribute, Container $container): array
    {
        $resolving = $container->currentlyResolving(); // Production::class

        return resolve(Registrar::class)->for($resolving);
    }
}

Note: I was unsure the best way to test this since Container::$buildStack is not modified until Container::build() is called which is after the before callbacks. The resolving item is also popped off Container::$buildStack before the after callbacks.

@jrseliga jrseliga force-pushed the expose-container-currently-resolving branch from db5cbb3 to f6be612 Compare May 8, 2025 19:22
@rodrigopedra
Copy link
Contributor

First, the changes to the Container interface should be sent to master on a separate PR. Adding a public method to a concrete class is allowed on patch releases, but not to an interface.

I added this test case on my local branch to the Illuminate\Tests\Container\ContainerTest class:

public function testCurrentlyResolving()
{
    $container = new Container;

    $container->afterResolvingAttribute(ContainerCurrentResolvingAttribute::class, function ($attr, $instance, $container) {
        $this->assertEquals(ContainerCurrentResolvingConcrete::class, $container->currentlyResolving());
    });

    $container->when(ContainerCurrentResolvingConcrete::class)
        ->needs('$currentlyResolving')
        ->give(fn ($container) => $container->currentlyResolving());

    $resolved = $container->make(ContainerCurrentResolvingConcrete::class);

    $this->assertEquals(ContainerCurrentResolvingConcrete::class, $resolved->currentlyResolving);
}

This would test both when an attribute is being resolved, and when a contextual binding is being resolved.

At the end of this same file, I added these helpers classes:

#[Attribute(Attribute::TARGET_PARAMETER)]
class ContainerCurrentResolvingAttribute implements ContextualAttribute
{
    public function resolve()
    {
    }
}

class ContainerCurrentResolvingConcrete
{
    public $currentlyResolving;

    public function __construct(
        #[ContainerCurrentResolvingAttribute]
        string $currentlyResolving
    )
    {
        $this->currentlyResolving = $currentlyResolving;
    }
}

@jrseliga
Copy link
Contributor Author

jrseliga commented May 8, 2025

Thanks @rodrigopedra! I'll add these tests and pull out the interface update to a PR against master.

@taylorotwell taylorotwell merged commit 7771d14 into laravel:12.x May 9, 2025
23 checks passed
@taylorotwell
Copy link
Member

Oops, merged after reverting the interface change. @jrseliga can you send the test in another PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.