Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repository in Controller or Model?

I've been working through the NerdDinner Tutorial and most of it makes sense. What I'm not sure about is why the Repository is used directly in the Controller and not the Model objects. For instance, if we wanted to implement our own membership system and it had an AccountController with a Login method, what would be the best solution for hooking it up? e.g.

Login(username,password){

    repo = AccountRepository

    account = repo.getLogin(username,password)

    //check account isn't locked

    //check account has been verified etc etc 

    //throw error or proceed to secure area

}

OR

Login(username,password){

    repo = AccountRepository

    account = repo.getLogin(username,password)

    account.login() //business logic is handled in Account (Model)

}

OR

Login(username,password){

    //no reference to repository

    account = Account

    //Account (Model) uses repository and handles business logic
    account.login(username,password) 

}

I'm suggesting having the Account object use the AccountRepository directly, instead of the AccountController getting the information from the AccountRepository and then passing it to the Account object e.g.

NerdDinnner style:

1 Login request comes in
2 AccountController uses AccountRepository to get login details based on request
3 AccountController uses Account object and passes in info from step 1
4 Account object processes request and notifies AccountController

What I'm suggesting:

1 Login request comes in
2 AccountController uses Account object to process login based on request
3 Account object uses AccountRepository to get login details
4 Account object processes request and notifies AccountController

The reason for the latter style is that after login details are returned from the AccountRepository there would be business rules to follow e.g. is account locked, is account verified etc If the first style is used the logic for getting the details and then using them is split over 2 steps. The latter style keeps all the logic together while still using the AccountRepository e.g.

Account.Login(username,password){
    repo = AccountRepository

    account = repo.GetLogin(username,password)

    //check account isn't locked

    //check account has been verified etc etc

    //throw error or proceed to secure area
}

I hope that makes sense.

like image 751
atwrok8 Avatar asked May 15 '09 22:05

atwrok8


4 Answers

The "model" in mvc is a presentational model not a domain model. You can consider the model in MVC as a Data Transfer Object used by the Controller to feed the view engine. The controller is the only actor connected with the service layer.

like image 61
Andrea Balducci Avatar answered Nov 15 '22 03:11

Andrea Balducci


You should at least have another layer (not the controller) that is responsible to interact with a repository interface. Thil allows to change de UI (the controller is a part of it) for another. In this way, it doesn't matter if it's a command line, desktop or web interface.

In ASP.NET MVC I prefer to have the model (not my domain model, the MVC one) in a separate project, not into the MVC one. This allows to share the DTOs (the MVC model) with other kind of UIs.

like image 39
bloparod Avatar answered Nov 15 '22 03:11

bloparod


Repository is an infrastructure concern. What you are doing is making your model rely on your infrastructure. That is kind of a backward way of doing it. It means that if you wanted to do things like use dependency injection you would then have to resolve your model from your container which doesn't make much sense to me.

Also the point is not really to keep everything in once place. You should be striving to keep your concerns separated into logical units. This way you can easily identify what part of the application does what. It also lends itself to testing.

like image 28
Derek Ekins Avatar answered Nov 15 '22 04:11

Derek Ekins


I would say that it is not the account that performs the login, but you use the account to login to the application, so calling the Login method on the account seems a little bit unnatural.

In Domain Driven Design there is a place for business logic which does not fit into the Account class: this is called a service. You can read more on DDD services e.g. here.

like image 30
bbmud Avatar answered Nov 15 '22 03:11

bbmud