简体   繁体   中英

Issue with dependency injection in laravel

I just learnt of laravel's service container and dependency injection, in order to try this out I created a MailgunServiceProvider to instantiate mailgun client, I laso have a trait called SendMail which acts as a wrapper for Mailgun:

However the $mailgun variable returns null, I'm getting the following message:

message Call to a member function messages() on null
exception   Symfony\Component\Debug\Exception\FatalThrowableError
file    C:\xampp\htdocs\dogmedia.com\app\Traits\SendMail.php
line    24

MailgunServiceProvider

<?php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Mailgun\HttpClientConfigurator;
use Mailgun\Mailgun;



class MailgunServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(Mailgun::class, function()
        {
            return Mailgun::create(config('mail.mailgun.secret'), 'https://api.eu.mailgun.net');
        });
    }
}

And my trait:

<?php
namespace App\Traits;

use Mailgun\Mailgun;


trait SendMail
{

    protected $mailgun;

    public function __construct(Mailgun $mailgun)
    {
        $this->mailgun = $mailgun;
    }


    public function sendMail($view, $mailData, $subject, $to)
    {
        //dd($this->mailgun); this returns null

        $html = view($view, compact('mailData'))->render();

        $result = $this->mailgun->messages()->send(config('mail.mailgun.domain'), [
            'from' => config('mail.from.name').' <'.config('mail.from.address').'>',
            'to' => $to,
            'subject' => $subject,
            'html' => $html,
        ]);

        return $result;
    }


}

This is the class inviking my trait.

<?php
namespace App\Http\Controllers;


use Mailgun\Mailgun;
use Illuminate\Http\Request;
use App\Http\Validators\ContactValidator;
use App\Models\General;
use App\Models\Post;
use App\Traits\SendMail;


class ContactController extends Controller
{
    use SendMail;


    public function __construct(){}


    public function sendContactMail1(Request $request)
    {
        //$validatedData = $request->validate(ContactValidator::$sendContactMail1);

        $mailData = 
        [
            'phone'=> $request->input('phone')
        ];

        $mail = $this->sendMail('emails.contacts.contact-mail-1', $mailData, 'Nuevo contacto en '.config('app.name'), 'gabogabans@gmail.com');

        return response()->json([
            'mail' => $mail,
        ]);
    }


}

The methods defined in the class definition will take priority over the trait methods. So if your class has a constructor defined then the trait's constructor method will not be applied.

"An inherited member from a base class is overridden by a member inserted by a Trait. The precedence order is that members from the current class override Trait methods, which in turn override inherited methods." PHP Manual - Traits - Precedence

class RandomClass
{
    use SendMail;

    public function __construct()
    {
    }
}

The constructor defined in the class will be used instead of the method with the same name from the trait.

You could avoid dealing with the constructor completely by having the sendMail method get an instance of the Mailgun class that you need from the container instead, if you prefer:

$mailgun = app(\Mailgun\Mailgun::class);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM