无法将类实例传递给构造函数 [英] Can't pass class instance to constructor

查看:67
本文介绍了无法将类实例传递给构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个User雄心勃勃的模型,该模型在其构造函数中采用了UserMailer类的实例,但出现此错误

I have a User eloquent model that takes in an instance of the UserMailer class in its constructor but I get this error

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

我理解该错误,但无法弄清楚我做错了什么,但是我不太了解命名空间和composer类映射与psr0自动加载的关系.我记得使用composer dump-autoload,不是那样的

I understand the error but can't figure out what I have done wrong but I don't udnerstanding namespacing and composer class map vs psr0 autoloading very well. I have remembered to use composer dump-autoload so it is not that

相关文件夹结构

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

composer.json自动加载部分. psr-0部分是从我添加验证服务开始的,您可以在TrainerCompare/中看到这些部分,这些类工作得很好.我按照本教程将app/TrainerCompare/Mailers添加到类映射中,以加载mailer类

composer.json autoload section. psr-0 section is there from when I added the validation service you can see in TrainerCompare/ and these classes work great. I added app/TrainerCompare/Mailers to the classmap per the tutorial I am following to get the mailer classes loaded

"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

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

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);
    }
}

推荐答案

口才(re)通过调用在内部创建自己:

Eloquent (re)creates itself internally by calling:

new static

一个示例是创建一个新查询:

An example is in creating a new query:

return with(new static)->newQuery();

我不确定在这种情况下是否可以使用自动依赖关系解析,它应该始终在laravel中运行,但是由于它也具有自己的构造函数方法,因此您至少必须转发对其的调用并支持$attribute参数:

I'm not sure if automatic dependency resolution would work in this case, it should always work inside laravel, but as it also has it's own constructor method, you must at least forward a call to it and support the $attribute parameter:

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

    parent::__construct($attributes);
}

编辑

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

Opened an issue to understand it: https://github.com/laravel/framework/issues/3862

编辑2

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

As I've said in comment, you better create a service, as pointed by yourself, is a better application design. You should not be using your model to send e-mails. A service that receives a user model (or just name and e-mail) and send the message to that user would be a better way to go.

泰勒·奥特威尔(Taylor Otwell)在本期中对此的回答:

Answer given by Taylor Otwell about it in the issue:

模型并不是真的要以这种方式将依赖项注入到模型中. 我猜想,这只是ActiveRecord风格的ORM的一种. 我建议将User传递给Mailer类或类似的类. 或者,如果您对此感到满意,则可以使用App :: make来获取 来自模型实例的邮件,尤其是在您仅需要该依赖项的情况下 从单一方法开始.

Models aren't really meant to have dependencies injected into them that way. Kind of just the style of ActiveRecord style ORMs I guess. I would suggest passing the User to a Mailer class or something similar. Or if you're comfortable with it you could use App::make to grab an instance of Mail from the model instance, especially if you only need that dependency from a single method.

这篇关于无法将类实例传递给构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆