Defining __constructor
within trait is actually wrong. Or just a bad design. Constructors should be specific to a class to which they belong, not traits. Another issue then, you're importing trait in Model class, that means you should specifically follow its rule about how a trait in a model is loaded.
At the boot
ing stage of a model, it searches imported traits recursively within class and automagically call a method that is using boot{TraitNameHere}
naming convention, statically. That proves traits in model does not involved in Laravel's dependency injection cycle.
To make it happen, you can use Laravel global helper to load stored instance inside container, like the facade App::make(DefinedKeyHere)
. Then store the assigned instance into a static property to make it retained until the runtime ends and also because the recalling method is static
.
trait TimezoneTrait
{
protected static $userRepository;
protected static function bootTimezoneTrait()
{
static::$userRepository = \App::make(UserRepositoryInterface::class);
}
}
If you're currently trying to avoid using global helper, listening to the model booting event is also helpful. Example inside EventServiceProvider,
Event::listen('eloquent.booting:*', function (Model $model) {
$model->setUserRepository($this->app[UserRepositoryInterface::class]);
});
Then the trait would be,
trait TimezoneTrait
{
protected static $userRepository;
public function static setUserRepository(UserRepositoryInterface $userRepository)
{
static::$userRepository = $userRepository;
}
}
Take a note that I defined setUserRepository
as static, but you can also make it non-static, too.
And to expand a little bit about model event, model has several events to fire whenever it's doing its related action.
Example events from Laravel 5.5,
public function getObservableEvents()
{
return array_merge(
[
'creating', 'created', 'updating', 'updated',
'deleting', 'deleted', 'saving', 'saved',
'restoring', 'restored',
],
$this->observables
);
}
And other two default events that are fired when its instantiated (also unserialized) which are booting
and booted
. And the method which is use to fire the event, notice the event name.
protected function fireModelEvent($event, $halt = true)
{
// ...
return ! empty($result) ? $result : static::$dispatcher->{$method}(
"eloquent.{$event}: ".static::class, $this
);
}