php – Laravel 4 – 子构造函数调用具有依赖注入的父构造函数

我正在使用Laravel 4构建CMS,我有一个基本的管理控制器,用于管理页面,如下所示:

class AdminController extends BaseController {

    public function __construct(UserAuthInterface $auth, MessagesInterface $message, ModuleManagerInterface $module)
    {
        $this->auth = $auth;
        $this->user = $this->auth->adminLoggedIn();
        $this->message = $message;
        $this->module = $module;
    }
}

Im使用Laravel的IOC容器将类依赖性注入到构造函数中。然后我有各种控制器类来控制构成CMS的不同模块,每个类都扩展了管理类。例如:

class UsersController extends AdminController {

    public function home()
    {
        if (!$this->user)
        {
            return Redirect::route('admin.login');
        }
        $messages = $this->message->getMessages();
        return View::make('users::home', compact('messages'));
    }
}

现在,这完全可以完成,但是当我将一个构造函数添加到UsersController类中时,我的问题就是一个更少的问题和更多的效率问题。例如:

class UsersController extends AdminController {

    public function __construct(UsersManager $user)
    {
        $this->users = $users;
    }

    public function home()
    {
        if (!$this->user)
        {
        return Redirect::route('admin.login');
        }
        $messages = $this->message->getMessages();
        return View::make('users::home', compact('messages'));
    }
}

因为子类现在有一个构造函数,这意味着父构造函数没有被调用,因此子类依赖于这个,所以这个用户不再有效,导致错误。我可以通过parent :: __ construct()调用管理控制器的构造函数,因为我需要传递类依赖关系,我需要在子构造函数中设置这些依赖关系,从而产生如下所示的东西:

class UsersController extends AdminController {

    public function __construct(UsersManager $user, UserAuthInterface $auth, MessagesInterface $message, ModuleManagerInterface $module)
    {
        parent::__construct($auth, $messages, $module);
        $this->users = $users;
    }

    // Same as before
}

现在这样做的功能很好,然而,我必须将父项的依赖项包含在具有构造函数的每个子类中似乎都不是很有效率。它也看起来相当凌乱。 Laravel是否提供了一个方法,或者PHP支持调用父和子构造函数的方式,而不必从子进程调用parent :: __ construct()?

我知道这是一个长期的问题,什么是有效的不是一个问题,但更多的我只是关于效率,但我感谢任何想法和/或解决方案。

提前致谢!

最佳答案
有一种方法
当BaseController自动解析它的依赖关系时。

use Illuminate\Routing\Controller;
use Illuminate\Foundation\Application;

// Dependencies
use Illuminate\Auth\AuthManager;
use Prologue\Alerts\AlertsMessageBag;

class BaseController extends Controller {

    protected $authManager;
    protected $alerts;

    public function __construct(
        // Required for resolving
        Application $app,

        // Dependencies
        AuthManager $authManager = null,
        AlertsMessageBag $alerts = null
    )
    {
        static $dependencies;

        // Get parameters
        if ($dependencies === null)
        {
            $reflector = new \ReflectionClass(__CLASS__);
            $constructor = $reflector->getConstructor()
            $dependencies = $constructor->getParameters();
        }

        foreach ($dependencies as $dependency)
        {
            // Process only omitted optional parameters
            if (${$dependency->name} === null)
            {
                // Assign variable
                ${$dependency->name} = $app->make($dependency->getClass()->name);
            }
        }


        $this->authManager = $authManager;
        $this->alerts = $alerts;

        // Test it
        dd($authManager);
    }
}

所以在子控制器中你只传递应用程序实例:

class MyController extends BaseController {

    public function __construct(
        // Class dependencies resolved in BaseController
        //..

        // Application
        Application $app
    )
    {
        // Logic here
        //..


        // Invoke parent
        parent::__construct($app);
    }
}

当然,我们可以使用Facade来应用

转载注明原文:php – Laravel 4 – 子构造函数调用具有依赖注入的父构造函数 - 代码日志