I am trying to override the default implementation of Mailer
in Illuminate\Mail\MailServiceProvider
.
At first, I thought that I will just extend the service and switch the implementation in the container followingly:
App\Mail\Mailer
<?php
namespace App\Mail;
class Mailer extends \Illuminate\Mail\Mailer
{
public function getTo()
{
return $this->to;
}
}
App\Providers\AppServiceProvider
<?php
namespace App\Providers;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton('mailer', function (Container $app) {
// ...
$mailer = new \App\Mail\Mailer(
$app['view'], $app['swift.mailer'], $app['events']
);
// ...
return $mailer;
});
}
}
The problem is that even though I've overridden the container definition when resolving the service it ignores my definition completely because
Illuminate\Mail\MailServiceProvider
has$defer = true
property, meaning that it will get resolved in a special way like this:
Illuminate\Foundation\Application
public function make($abstract)
{
$abstract = $this->getAlias($abstract);
if (isset($this->deferredServices[$abstract])) {
$this->loadDeferredProvider($abstract);
}
return parent::make($abstract);
}
So, it doesn't matter that I tried to override the service, because Illuminate\Mail\MailServiceProvider
will always get preferred since it's deferred
service provider. I tried defining my service provider as $defer = true
as well but without luck.
The only option that I can think of would be to completely remove Illuminate\Mail\MailServiceProvider
and replace it with a custom one. But that seems a bit harsh.
Any ideas?
The only way to solve this issue is to upgrade Laravel to version 5.5
and above. The fixed version is referenced in this issue and won't be fixed in 5.4
since the version is no longer supported.