最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

dependency injection - How to unset scoped instances from the DI Container in laravel - Stack Overflow

programmeradmin1浏览0评论

I've currently been struggling on unsetting a scoped instance from laravels DI container. To reproduce and unserstand, please see the following test:

it('should be able to remove scoped instances', function () {
    class TestClass
    {
        public function __construct(
            public int $count,
        ) {
        }
    }

    function testResolveClass($class, array $args = []): object
    {
        if (! app()->bound($class)) {
            $instance = app($class, $args);
            app()->scoped($class, fn (Application $app) => $instance);
        }

        return app($class);
    }

    // Create first instance
    $instance = testResolveClass(TestClass::class, ['count' => 123]);
    $id = spl_object_id($instance);

    // Unset instances
    unset($instance);
    app()->forgetScopedInstances(); // TODO Why doesnt this unset the instance?

    // unset(app()[TestClass::class]); // would work because it also unsets the variables 'binding' and 'resolved', but cannot be done in my case

    // Create another instance (at least we try to...)
    $instance = testResolveClass(TestClass::class, ['count' => 456]);
    $id2 = spl_object_id($instance);

    // Expect the object id is not the same and the count changed
    expect()
        ->and($id2)->not->toBe($id) // fails because id is the same
        ->and($instance->count)->toBe(456); // would fail because count is 123
});

Is my approach wrong, am I missing something or would you expect this behaviour aswell?

If I could check if the instance was forgotten, I could at least rebind the instance manually, but I cannot seem to find any check if a scoped instance is really bound or was unbound after calling app()->forgetScopedInstances();.

Many thanks, michiruf

I've currently been struggling on unsetting a scoped instance from laravels DI container. To reproduce and unserstand, please see the following test:

it('should be able to remove scoped instances', function () {
    class TestClass
    {
        public function __construct(
            public int $count,
        ) {
        }
    }

    function testResolveClass($class, array $args = []): object
    {
        if (! app()->bound($class)) {
            $instance = app($class, $args);
            app()->scoped($class, fn (Application $app) => $instance);
        }

        return app($class);
    }

    // Create first instance
    $instance = testResolveClass(TestClass::class, ['count' => 123]);
    $id = spl_object_id($instance);

    // Unset instances
    unset($instance);
    app()->forgetScopedInstances(); // TODO Why doesnt this unset the instance?

    // unset(app()[TestClass::class]); // would work because it also unsets the variables 'binding' and 'resolved', but cannot be done in my case

    // Create another instance (at least we try to...)
    $instance = testResolveClass(TestClass::class, ['count' => 456]);
    $id2 = spl_object_id($instance);

    // Expect the object id is not the same and the count changed
    expect()
        ->and($id2)->not->toBe($id) // fails because id is the same
        ->and($instance->count)->toBe(456); // would fail because count is 123
});

Is my approach wrong, am I missing something or would you expect this behaviour aswell?

If I could check if the instance was forgotten, I could at least rebind the instance manually, but I cannot seem to find any check if a scoped instance is really bound or was unbound after calling app()->forgetScopedInstances();.

Many thanks, michiruf

Share Improve this question asked yesterday michirufmichiruf 4231 gold badge7 silver badges13 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Your test code is invalid. In your test you use:

$instance = app($class, $args);
app()->scoped($class, fn (Application $app) => $instance);

It seems wrong to me to retrieve the instance from the container in the first line and then return it as part of a scoped instance in the second one.

When you change your code to the following, it will likely work as expected:

// No $instance variable here used.
app()->scoped($class, fn (\Illuminate\Foundation\Application $app) => new $class(...$args));
发布评论

评论列表(0)

  1. 暂无评论