Laravel 的 routing 是如何支援開發者使用 method injection?

前陣子參加線上讀書會,聊到 Laravel 5 的 controller 允許開發者使用 method injection

好奇是如何做到的?

今天 trace 了一下,發現此功能寫在 Illuminate\Routing\RouteDependencyResolverTrait 裡面

然後 Illuminate\Routing\ControllerDispatcher 使用了此 trait

並且在此處呼叫

protected function call($instance, $route, $method)
{
    $parameters = $this->resolveClassMethodDependencies(
        $route->parametersWithoutNulls(), $instance, $method
    );

    return $instance->callAction($method, $parameters);
}

這就是 Laravel 5 controller 提供 method injection 的地方。

順帶一提,直接用 closure 的 routing 寫法的話,一樣支援 method injection

它在 Illuminate\Routing\Route 使用了此 trait

並且在此處呼叫

protected function runCallable(Request $request)
{
    $parameters = $this->resolveMethodDependencies(
        $this->parametersWithoutNulls(), new ReflectionFunction($this->action['uses'])
    );

    return call_user_func_array($this->action['uses'], $parameters);
}