Link to home
Start Free TrialLog in
Avatar of SheppardDigital
SheppardDigital

asked on

Controller and Repository pattern query

Hi,

I'm currently trying to integrate the repository pattern into my own MVC framework.

I'm working on the basis of having a 'BaseModel' and each Model/Entity will extends that.

class User extends BaseModel {}

Open in new window


In the past I've have the Model talk directly to a database class, I believe this would be called the Active Record Pattern. I'm trying to move away from it for a project.

I've created a BaseRepository class which will contain generic methods such as all(), get(), save(), delete(). Repositories will extends this class.

class UserRepository extends BaseRepository {}

Open in new window


The general methods(all,get,save,delete) will use the Repository name to work out which Model it should create when returning objects, i.e. UserRepository becomes User ($object = new $className()).

Anyway, my main questions is what would be considered the best way (best practice) of using the Repositories in a controller?

The first, uses static method on the Repository class. In this case, the static class would talk to a database class, get the rows, and for each row create a new User object and return these in an array.
public function index() {
     $users = UserRepository::all();
}

Open in new window


The second way is to not use static methods.
public function index() {
     $userRepo = new UserRepository();
     $users = $userRepo->all();
}

Open in new window


The third way is to initiate the repository in the __construct() method of the controller.
class UserController {
     private $UserRepository;

     public function __construct() {
          $this->UserRepository = new UserRepository();
     }

     public function index() {
          $users = $this->UserRepository->all();
     }
}

Open in new window


I believe there is a fourth way, which would involve injecting the Repository into the controller, which I guess is better for testing as you can pass over a different repository(i.e. one that simply uses arrays). I don't really understand how this works when you need to use multiple repositories in your Controller.
class UserController {
     private $UserRepository;

     public function __construct(UserRepository $repository) {
          $this->UserRepository = $repository
     }

     public function index() {
          $users = $this->UserRepository->all();
     }
}

Open in new window


I do wonder if it could be best to use a mixture of the 3rd and 4th way.
class UserController {
     private $userRepository;
     private $DepartmentRepository;

     public function __construct() {
          $this->UserRepository = new UserRepository;
          $this->DepartmentRepository = new DepartmentRepository;
     }

     public function overrideRepositories(UserRepository $userRepository,DepartmentRepository $deptRepository) {
          $this->userRepository = $userRepository;
          $this->departmentRepository = $deptRepository;
     }

     public function index() {
          $users = $this->UserRepository->all();
     }
}

$controller = new UserController();
$controller->overrideRepositories(new UserRepository(),new DepartmentRepository());
$controller->index();

Open in new window

Above above code means that during normal usage, the construct() method creates the Repositories, but when testing the overrideRepositories() method can be used to override those set by the construct() method, and we could pass over a repository that uses arrays or MongoDB.

I'm really just looking for some feedback on the above and which you would recommend. Am I even going about things the write way?
ASKER CERTIFIED SOLUTION
Avatar of Member_2_248744
Member_2_248744
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial