0

I'm trying add dependency injection on User class and after few hours trying, I found this way:

  • I added this code to App\Models\User class
    public function __construct()
    {
        $this->roleService = resolve(RoleService::class);
    }
  • I've checked $this->roleService value, it work normally, buut when I try to use it in a function:
    public function isAdmin() {
        return $this->roleService->isAdmin($this->role_id);
    }
  • This function throw an error Call to a member function isAdmin() on null. When I logged $this->roleService, it returned null.

Anyone can solve this?

simpsons3
  • 880
  • 1
  • 11
  • 29
  • Have you declared `protected $roleService;` variable before your constructor ? Also don't you think your constructor should be like this `public function __construct(User $user)` and then `$this->roleService = $user;` ? – Vipertecpro Feb 13 '20 at 06:02
  • + I tried to declare ```$roleService``` and it doesn't work. I think it isn't matter because I've tried to remove it on other class and it worked normally. + If I modify constructor to ```public function __construct(User $user)```, it probably throw error because constructor of Model parent class initialized with 1 parameter like this ```__construct(array $attributes = array())``` – simpsons3 Feb 13 '20 at 07:41
  • Can you please dd this `dd( $this->roleService)` in isAdmin() and in __construct() – Vipertecpro Feb 13 '20 at 08:10
  • using in ```__construct()``` returned instance of ```RoleService``` class but using in ```isAdmin()``` return ```null``` – simpsons3 Feb 13 '20 at 08:53
  • That's great that you've resolved it, could you update your answer with code which you've refactored ? – Vipertecpro Feb 13 '20 at 09:47
  • Unfortunately, I'm doing it and getting stuck for hours :D – simpsons3 Feb 13 '20 at 10:14

2 Answers2

0

Create a custom accessor for your model, and get/set the value from there.

public function getRoleServiceAttribute ()
{
    if(is_null($this->roleService)){
        $this->roleService = resolve(RoleService::class);
    }

    return $this->roleService;
}

Then you can access the attribute as $this->role_service

Also make sure you declare the $roleService class property as protected, to avoid accidental access as $this->roleService from anywhere else.

Ahmed Shefeer
  • 386
  • 2
  • 12
0

Thank for help. I just have referenced answer of an expert. He said that we should not dependency injection in Model class because it will broke project structure. Project should be followed structure: Controller->Service->Repository->Model->Database. So, I'll refactor my code follow it.

simpsons3
  • 880
  • 1
  • 11
  • 29