I am trying to override the default implementation of Mailer
in IlluminateMailMailServiceProvider
.
At first, I thought that I will just extend the service and switch the implementation in the container followingly:
AppMailMailer
<?php namespace AppMail; class Mailer extends IlluminateMailMailer { public function getTo() { return $this->to; } }
AppProvidersAppServiceProvider
<?php namespace AppProviders; class AppServiceProvider extends ServiceProvider { public function register() { $this->app->singleton('mailer', function (Container $app) { // ... $mailer = new AppMailMailer( $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
IlluminateMailMailServiceProvider
has$defer = true
property, meaning that it will get resolved in a special way like this:
IlluminateFoundationApplication
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 IlluminateMailMailServiceProvider
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 IlluminateMailMailServiceProvider
and replace it with a custom one. But that seems a bit harsh.
Any ideas?
Advertisement
Answer
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.