不能将类实例传递给构造函数


Can't pass class instance to constructor

我有一个usereloquent模型,在其构造函数中接受UserMailer类的实例,但我得到这个错误

Argument 1 passed to User::__construct() must be an instance of TrainerCompare'Mailers'UserMailer, none given, called in /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php on line 631 and defined

我理解错误,但无法找出我做错了什么,但我不理解命名空间和作曲家类映射vs psr0自动加载很好。我记得使用composer dump- autolload,所以它不是

相关文件夹结构

composer.json
app/
  models/
    User.php
  TrainerCompare/
    Mailers/
      Mailer.php
      UserMailer.php
    Services/
      Validation/

作曲家。Json自动加载部分。psr-0部分是从我添加验证服务时开始的,您可以在TrainerCompare/中看到,这些类工作得很好。我根据教程将app/TrainerCompare/Mailers添加到类映射中,以加载mailer类

"autoload": {
        "classmap": [
            "app/commands",
            "app/controllers",
            "app/models",
            "app/database/migrations",
            "app/database/seeds",
            "app/tests/TestCase.php",
            "app/tests/helpers",
            "app/TrainerCompare/Mailers"
        ],
        "psr-0":{
            "TrainerCompare": "app/"
        }
    }

User.php

<?php
use Illuminate'Auth'UserInterface;
use Illuminate'Auth'Reminders'RemindableInterface;
use TrainerCompare'Mailers'UserMailer as Mailer;
class User extends BaseModel implements UserInterface, RemindableInterface
{
    protected $mailer;
    public function __construct(Mailer $mailer)
    {
        $this->mailer = $mailer;
    }
}

Mailer.php

<?php namespace TrainerCompare'Mailers;
use Mail;
/**
* Email mailing class
*/
abstract class Mailer
{
    public function __construct()
    {
        # code...
    }
    public function sendTo($user, $subject, $view, $data = [])
    {
        Maill::send($view, $data, function ($message) use ($user, $subject) {
            $message->to($user->email)
                    ->subject($subject);
        });
    }
}

UserMailer.php

<?php namespace TrainerCompare'Mailers;
use User;
/**
* User Mailer Class
*/
class UserMailer extends Mailer
{
    public function __construct()
    {
        # code...
    }
    public function welcome($user)
    {
        $view = 'emails.users.welcome';
        $data = [];
        $subject = 'Welcome to Laracsts';
        return $this->sendTo($user, $subject, $view, $data);
    }
}

Eloquent (re)通过调用:

new static
一个例子是创建一个新的查询:
return with(new static)->newQuery();

我不确定自动依赖解析是否会在这种情况下工作,它应该总是在laravel内工作,但由于它也有自己的构造函数方法,您必须至少转发对它的调用并支持$attribute参数:

public function __construct(array $attributes = array(), Mailer $mailer)
{
    $this->mailer = $mailer;
    parent::__construct($attributes);
}

编辑

打开一个问题来理解它:https://github.com/laravel/framework/issues/3862

编辑2

正如我在评论中所说的,你最好创建一个服务,正如你自己指出的,是一个更好的应用程序设计。你不应该用你的模型发送电子邮件。一个接收用户模型(或者只是名称和电子邮件)并将消息发送给该用户的服务将是更好的方式。

Taylor Otwell对问题的回答:

模型并不是真的要以这种方式注入依赖关系。有点像ActiveRecord样式的orm。我建议将User传递给Mailer类或类似的东西。或者,如果你不介意的话,你可以使用App::make来获取的实例来自模型实例的邮件,特别是当您只需要该依赖项时