How to implement a "thin"

8

I'm working on a prototype of an ASP.NET MVC application, where I want to leave my lean controller (with the least amount of code possible) for that, not doing business logic on it, but yes in the business layer.

I have the business layer, where I have my class Usuario , and in this layer I have interfaces that should be implemented by other layers. I'll be using dependency injection.

My question is how to notify my controller of what worked or not, to notify or redirect the user, for example, when my controller calls Usuario.Cadastrar() , there may be an error filling the data, the password may not meet the security requirements, the email may already be registered or there may be an error in sending the confirmation email.

What should the Register method return to the Controller ? An enumerator like ( ErroEnviarEmail , SenhaFraca , EmailCadastrado ), a Exception for each possible path? A string etc.

public class Usuario
{
    public Usuario()
    {

    }

    public Usuario(IUsuarioRepositorio repositorio, ISeguranca seguranca, IEnviaEmail email)
    {
        this.repositorio = repositorio;
        this.seguranca = seguranca;
        this.email = email;
    }

    private IUsuarioRepositorio repositorio;
    private ISeguranca seguranca;
    private IEnviaEmail email;

    public int Codigo { get; set; }
    public string Email { get; set; }
    public string Senha { get; set; }


    public bool Cadastrar()
    {
        if (this.ValidarPreenchimento())
        {
            if (this.seguranca.ValidarSegurancaSenha(this.Senha))
            {
                if (!this.repositorio.EmailCadastrado(this.Email))
                {
                    this.Senha = seguranca.Criptografar(this.Senha);
                    this.repositorio.Inserir(this);
                    this.email.EnviarEmailCadastro(this);
                    return true;
                }
            }
        }       
        return false;
    }

    private bool ValidarPreenchimento()
    {
        if (string.IsNullOrEmpty(this.Email))
            return false;

        if (string.IsNullOrEmpty(this.Senha))
            return false;

        return true;
    }

}
    
asked by anonymous 24.11.2015 / 23:30

2 answers

8

I imagine you will have a hard time doing anything that might be called "thin" when you talk about so many layers. Lasagna does not combine with thinness. Taking the business rule out of the controller , it is not making him thin is fixing an error that had been committed.

controller does not have to be notified of anything. It invokes the model , which should execute everything it needs and informs the controller via return.

Probably will call the Usario.Cadastrar() in the model and the Boolean return of this method should be whether your notification worked or not. At least that seems to be his intention.

Rich error information

Ok, you want to return other possible problems. There are alternatives .

I would probably return an enumeration. Or an object that gives more information that can be used in the view and possibly some member of it in controller . This object could look like an exception, though it may not be one. Read more about the link above.

Some people say that I should use exception, but I would not go this way to indicate business logic problem. Mainly to use as demonstrated in the other response. Besides not solving your problem, it causes others.

Depending on the context you might even use the exception, or another solution not described here, but without understanding the problem as a whole is difficult to state, I can only list alternatives.

But as a general rule do not use exceptions to handle business rules , and therefore are not exceptional. And validation is business rule .

    
24.11.2015 / 23:44
0

I would do it as follows:

  • Using validation by annotation even you solve all the information problems coming up wrong from the view.
  • Using try catch you treat all unexpected errors, and you can create exceptions for something more specific.

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Edit(VMObjeto obj)
        {
            if (ModelState.IsValid)
            {
           
              try{
                
                ... 
                //chamada do seu negocio
                ....
                
              catch (Exception ex)
               {
               
                 ... 
                 //seu tratamento de erro, usando a arquitetura que você quiser
                 
               }
              
             }
          
          }
    
24.11.2015 / 23:38