Laravel resolving dependencies for a closure

2019-07-17 06:31发布

Laravel is able to automatically inject dependencies in controller constructs, etc. For example:

class Test {
    public function __construct(Request $request) {}
}

App::make('Test');

The controller's constructor will receive the appropriate request facade.

Is there a way to do this with closures?

For example:

$closure = function(Request $input) {};
App::make($closure); // resolving the closure dependencies

1条回答
萌系小妹纸
2楼-- · 2019-07-17 07:13

No, it's not possible, you may read through the IoC container code here:

laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 466

As you see it tries to resolve and parse parents Class's __constructor method through reflections.

I think that would be interesting to implement, as it's quite possible by extending the Container class to also support closures.

I have made a couple of tests to make sure it is possible, so here they are:

    class t4 {
        public $x = "inject me";
    }

    interface t5 {}

    $t3 = function(t4 $test) {
        return print($test);
    };
    $r = new ReflectionFunction($t3);
    $params = $r->getParameters();
    $injection = $params[0]->getClass();
    if (!$injection->isInstantiable()) {
        throw new Exception('Provided type hint is not instantiable');
    }
    $typehinted = $injection->newInstance();
    print($typehinted->x); // prints "inject me"

Type hinting t5 will throw the exception.

This answers the question

Is there a way to do this with closures?

As to how implement it, in my opinion you should have perfect knowledge of how reflections and Laravel IoC container work. I think this will not be implemented in near future as Laravel is basically built on classes. What are your use cases?

查看更多
登录 后发表回答