Is there a way to send parameters to an Observer in Eloquent ORM?
Based on laravel's documentation:
User::observe(UserObserver::class);
observe
method receive a class, not an instance of an object. So I cant do something like:
$observer = new MyComplexUserObserver($serviceA, $serviceB)
User::observe($observer);
So, in my code I can do something like:
class MyComplexUserObserver
{
private $serviceA;
private $serviceB;
public function __constructor($serviceA, $serviceB){
$this->serviceA = $serviceA;
$this->serviceB = $serviceB;
}
public function created(User $user)
{
//Use parameters and services here, for example:
$this->serviceA->sendEmail($user);
}
}
Is there a way to pass parameters or services to a model observer?
Im not using
laravel
directly, but i'm using eloquent (illuminate/database
andilluminate/events
)Im not trying to send additional parameters to an explicit event like in: Laravel Observers - Any way to pass additional arguments?, i'm trying to construct an observer with additional parameters.
Thank you to @martin-henriksen.
use Illuminate\Container\Container as IlluminateContainer;
$illuminateContainer = new IlluminateContainer();
$illuminateContainer->bind(UserObserver::class, function () use ($container) {
//$container is my project container
return new UserObserver($container->serviceA, $container->serviceB);
});
$dispatcher = new Dispatcher($illuminateContainer);
Model::setEventDispatcher($dispatcher); //Set eventDispatcher for all models (All models extends this base model)
User::observe(UserObserver::class);
In the Illuminate events there is the line, this indicates on event subscription it utilities the container. This mean we can use this to our advantage, i'm not super familiar with non Laravel
bootstrapped applications. But where ever your app is defined, you will bind your class to your own class.
$container = new Container();
$container->bind(MyComplexUserObserver::class, function ($app) {
return new MyComplexUserObserver($serviceA, $serviceB, $theAnswerToLife);
});
$dispatcher = new Dispatcher($container);
This will result in, next time your application resolves your class, it will use this version of it and therefor you can setup your class as you intend.
Edit: an example how you can utilize the Laravel
container, to utilize the bind functionality.