5

According to the MVC design pattern, if we create a user (database work) and we have to send a mail with an activation code to the user, would this fit in the model or in the controller, after the model created the database record?

tereško
  • 58,060
  • 25
  • 98
  • 150
onlineracoon
  • 2,932
  • 5
  • 47
  • 66

3 Answers3

8

The MVC pattern is used to create an abstraction between the business logic (the model) and the GUI (the view). The controller is just an adapter (google adapter pattern) between those two blocks.

Hence the controller should only have code which is used to fetch the required information from the controller and adopt it so it fits the view. Any other logic should be in the model.

That only make sense if you understand that the model is not a single class but all of your business logic.

Example (implementation specific, but I hope that you understand):

public class UserController : Controller
{
    // notice that it's a view model and not a model
    public ActionResult Register(RegisterViewModel model)
    {
        UserService service;
        User user = service.Register(model.UserName);
        return View("Created");
    }
}

// this class is located in the "model"
public class UserService
{
   public User Register(string userName)
   {
       // another class in the "model"
       var repository = new UserRepository();
       var user = repository.Create(userName);

       // just another "model" class
       var emailService = new EmailService();
       emailService.SendActivationEmail(user.Email);

       return user;
   }
}
jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • that the controller should send the email. Which is false. business logic should not exist in the controller. – jgauffin Aug 27 '12 at 13:14
  • then who sends the email ? the model ? NOT ! the view ? NOT ! – Ionut Flavius Pogacian Aug 27 '12 at 13:15
  • 4
    You have not understood MVC if you are saying that the model should not send the email. – jgauffin Aug 27 '12 at 13:15
  • i take Yii MVC as example; the Controller sends the mail; the model its used strictly for interogations; but you can send mails even from models; – Ionut Flavius Pogacian Aug 27 '12 at 13:17
  • Several MVC frameworks (like ASP.NET MVC) uses view models which are very different from the model definition in the MVC pattern. Still. M in MVC is the business layer. And sending an email upon registration etc is a business rule. – jgauffin Aug 27 '12 at 13:19
  • What about 2 separated models, one for database, one for the mail, would that be a propper solution, ofcourse the controller only has access to those. – onlineracoon Aug 27 '12 at 13:20
  • @onlineracoon: i use the raise event method; i do have a separate class for mail events and others – Ionut Flavius Pogacian Aug 27 '12 at 13:22
  • 2
    The model is not a single class. The model can contain several classes per controller action. But you typically create a `UserService` class which has a `Register` method that in turn call `UserRepository` and `EmailService` to take the required actions. – jgauffin Aug 27 '12 at 13:23
  • The `UserService` can be used by several actions in the `UserController` (if required). Putting business logic inside the controller would also violate the Single Responsibility Principle – jgauffin Aug 27 '12 at 13:25
  • so, you say what i say now; if the controller is User, it has to instantiate a UserService and EmailService action class ? why not go in the model and call them ? :)) – Ionut Flavius Pogacian Aug 27 '12 at 13:32
  • and just to finish, look at the url when the request happens; its like controller/action not like model/action – Ionut Flavius Pogacian Aug 27 '12 at 13:33
  • I don't know what you are calling action classes, sounds implementation specific. But No. I'm saying that UserService has to instantiate the EmailService in it's Register method since it's a business rule and belongs in the business layer. – jgauffin Aug 27 '12 at 13:34
  • 1
    @IonutFlaviusPogacian , since you are a PHP developer, please, read [this](http://stackoverflow.com/a/5864000/727208). It might clear up some of your confusion. – tereško Aug 27 '12 at 14:44
3

MVC and MVC-inspired design patterns are combination of two layers:

  • Presentation layer
  • Model layer

Presentation layer is made up from views, controllers and (mostly in web-oriented solutions) templates. This layer deals with user interaction. It recognizes user input, produces responses and governs other aspect of user interface. The controllers, based on user interaction, change the state of model layer.

The model layer deals with domain business rules and interacts with different forms of storage. Model layer, just like presentation layer, is no any single object or class, but a group of structures with different responsibilities.

In this case, it would make sense for the service, which deals with user management, to use the different structures, that would both send the verification email, create an account and store this newly created user.

Services in model layer act like the barrier, that isolated the presentation layer from business logic. They deal with interaction between domain objects and storage abstractions (data mappers, repositories, units of work, etc.).

TL;DR

Email, with activation code for the newly created user, should be sent from model layer.

tereško
  • 58,060
  • 25
  • 98
  • 150
0

The controller is an object which simplifies and delegates messages to the model objects.

What you will have is an Interface object (or boundary object) within your model that represents the link between two systems (your system and email). class EmailClient. Your model objects will collaborate with this object when required.

Michael Brown
  • 498
  • 4
  • 13