Classes de utilitário no MVC - ASP.NET

15

Então, eu estava pensando hoje, onde você colocaria classes de utilitário em um aplicativo ASP.NET MVC? Por classes de utilidade, quero dizer classes que podem ser estáticas e são usadas apenas para executar uma função. Como uma classe para enviar um email que usa endereço de email, assunto e corpo como argumentos.
Eu suponho que talvez criar uma pasta e um espaço para nome separados seria bom o suficiente, mas queria obter opiniões de todos

user60812
fonte
3
Por que criar classes de utilidade em qualquer tipo de projeto? Por que o MVC é destacado na sua pergunta?
Oded
1
Bem, eu estava pensando sobre o MVC, porque de certa forma força a estrutura. E no que diz respeito à utilidade, fiquei com a impressão de que todos a usavam :) Se eu tenho um código de remetente de e-mail e o divido em uma classe separada para trabalhar com várias partes do sistema, não é uma classe de utilidade ou Eu confundi? Pensei classes de utilitários já foram reutilizáveis em qualquer programa que não está amarrado no código
user60812
Eu, pessoalmente, considero-mail enviando um serviço, captada por dizer a interface IUserNotificationSender ou assim .. com a manipulação de erro adequado, smtp configuração etc que não se encaixa em uma função de utilidade ...
Max
@ Max, então o que seria considerado uma função de utilidade? Eu estou tentando entender, como parece-me que estou muito confuso
user60812
Bem, uma função de utilidade adequada em minha mente é uma função muito pequena, com um escopo muito definido e sem dependências externas ... Como uma função para remover espaços em branco, aparar uma string ou obter o enésimo elemento de uma coleção ...
Max

Respostas:

11

Você não E seu próprio exemplo é perfeito para mostrar por que não.

Você quer enviar e-mails, certo? Então você cria em algum lugar uma classe estáticaCommunicationUtilities com uma estática SendEmail()nela. Você usa esse método de alguma classe que faz várias coisas; por exemplo, redefine a senha de um usuário e envia uma nova por email. Perfeito.

Agora, o que acontece se você quiser testar sua classe? Você não pode, porque toda vez que deseja testar o método que redefine a senha, ele altera o banco de dados (o que não é adequado para um teste de unidade) e, além disso, envia um e-mail (o que é ainda pior).

Você pode ter lido sobre a Inversão de controle, que tem o benefício de facilitar o teste de unidade. Os artigos sobre IoC explicarão que, em vez de fazer algo como:

void ResetPassword(UserIdentifier userId)
{
    ...
    new MailSender().SendPasswordReset(userMail, newPassword);
}

Você faz:

void ResetPassword(IMailSender sender, UserIdentifier userId)
{
    ...
    sender.SendPasswordReset(userMail, newPassword);
}

que permite usar zombarias e tocos.

Tente aplicar a IoC ao seu CommunicationUtilities. Certo, você não pode. É por isso que está quebrado.

Arseni Mourzenko
fonte
Oi MainMa, por isso, se eu entendi corretamente, é adequado ainda fazer uma classe de dizer fundo com toda a tubulação, abstraí-la com uma interface e passar a interface para a função em vez de chamar diretamente da classe como no seu primeiro snippet.
User60812
1
@ user60812: em resumo, leia sobre IoC. Seria difícil explicar todo o assunto em um simples comentário.
Arseni Mourzenko
1
Que tal uma função utilitária verdadeiramente genérica, como um truncador de string?
jbyrd
2
@MainMa - desculpe, eu não sigo. É como o que eu quero, sim. Mas Truncate () não está embutido no c #, então eu queria saber se faria sentido colocar esse tipo de função de utilitário genérica em algum tipo de classe de utilitários.
Jbyrd #
2
Essa resposta define o problema, observando que, nesse caso específico, nenhuma classe util é necessária. Mas, em geral, sempre existem alguns métodos de estilo "auxiliar" que não cabem em lugar algum.
usr
9

A pergunta é válida, mesmo que o exemplo dado não seja. A resposta dada por Maina é perfeita, em um contexto muito específico, que não é para mim, o contexto apropriado para as referidas classes de "utilidade" .

Pessoalmente, crio uma pasta Helpersna qual coloco funções simples para serem chamadas de qualquer lugar, como extensões; nesse caso, sim, elas são estáticas.

Agora, se houver uma maneira melhor, ficarei feliz em aprender, mas até agora:

  • Não vejo nada de errado com as extensões.
  • Não vejo nada de errado em agrupá-los em uma pasta específica.

Agora, uma extensão é apenas açúcar sintático, também poderia ser uma função clássica.

BernardG
fonte
6

Nenhuma das respostas fornecidas anteriormente aborda a questão real. O user60812 simplesmente perguntou onde colocar uma classe de utilidade dentro de um projeto MVC. Todos se interessaram pelo exemplo singular e falaram sobre tudo, exceto a pergunta em questão.

@ user60812, dependendo do nível de abstração que você deseja, gostaria:

  • A) Crie uma pasta e crie a classe de utilitário dentro dessa pasta
  • B) Crie um projeto para conter as classes de utilidade (assumindo o desejo de reutilizar a montagem).
  • C) Extrapole seus utilitários em uma arquitetura de serviço e chame-os

Aqui está um link para uma pergunta semelhante com melhores respostas.

Na minha humilde opinião

Spencer Sullivan
fonte
1

Não crie classes estáticas para utilitários. A estática é ruim na maioria dos casos. Não os chame de gerentes também. O que quer que você esteja trabalhando, deve ser colocado em um espaço de nome lógico.

Por exemplo:

namespace Application.Notifications.Email
{
   public interface ISendEmailCommand
   {
      void Execute(Email email);
   }
}

O endereço de email, o assunto e o corpo são uma preocupação separada; portanto, eu teria uma estrutura de classe para isso, daí o motivo pelo qual usei Email emailno exemplo acima.

CodeART
fonte
Explique por que as classes estáticas são ruins para manter os métodos utilitários? Estou genuinamente curioso quanto ao seu raciocínio.
Spencer Sullivan