Klasy narzędzi w MVC - ASP.NET

15

Zastanawiałem się dzisiaj, gdzie umieściłbyś klasy narzędzi w aplikacji ASP.NET MVC? Przez klasy użytkowe rozumiem klasy, które mogą być statyczne i służą do wykonywania funkcji. Jak klasa, która wysyła wiadomość e-mail, która przyjmuje jako argument argument adres, temat i treść.
Zakładam, że może utworzenie osobnego folderu i przestrzeni nazw byłoby wystarczająco dobre, ale chciałem uzyskać opinie wszystkich

użytkownik60812
źródło
3
Po co tworzyć klasy użyteczności w dowolnym projekcie? Dlaczego w twoim pytaniu wyróżniono MVC?
Oded
1
Cóż, zastanawiałem się nad MVC, ponieważ w pewien sposób wymusza strukturę. A jeśli chodzi o użyteczność, miałem wrażenie, że wszyscy ich używali :) Jeśli mam kod nadawcy wiadomości e-mail i podzielę go na osobną klasę do pracy z różnymi częściami systemu, czy nie jest to klasa użyteczności, czy jestem Myliłem się? Myślałem, że klasy użyteczności były kiedyś wielokrotnego użytku w dowolnym programie, który nie jest powiązany z kodem
10.09.13
Osobiście rozważyłbym wysłanie usługi e-mailem, abstrahując od powiedzenia interfejsu IUserNotificationSender lub coś takiego .. z odpowiednią obsługą błędów, konfiguracją smtp itp., Która tak naprawdę nie pasuje do funkcji narzędzia ...
Max
@Max, więc co byłoby uważane za funkcję narzędzia? Próbuję zrozumieć, jak mi się wydaje, jestem bardzo zdezorientowany
60812
Cóż, właściwa funkcja użyteczności w mojej opinii jest bardzo małą funkcją o ściśle określonym zakresie i bez zewnętrznych zależności ... Takich jak funkcja do usuwania białych znaków, przycinania łańcucha lub uzyskiwania n-tego elementu kolekcji ...
Maks.

Odpowiedzi:

11

Ty nie. A twój własny przykład jest idealny, aby pokazać, dlaczego nie.

Chcesz wysyłać e-maile, prawda? Więc tworzysz gdzieś klasę statyczną CommunicationUtilitiesze statyczną zawartością SendEmail(). Używasz tej metody z klasy, która robi mnóstwo rzeczy, na przykład resetuje hasło użytkownika i wysyła mu nowe przez e-mail. Doskonały.

Co się stanie, jeśli chcesz przetestować jednostkę w klasie? Nie możesz, ponieważ za każdym razem, gdy chcesz przetestować metodę, która resetuje hasło, zmienia bazę danych (co nie nadaje się do testu jednostkowego), a ponadto wysyła wiadomość e-mail (co jest jeszcze gorsze).

Być może przeczytałeś o Inwersji Kontroli, która ma tę zaletę, że ułatwia testowanie jednostek. Artykuły o IoC wyjaśniają, że zamiast robić coś takiego:

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

ty robisz:

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

co pozwala używać makiet i odcinków.

Spróbuj zastosować IoC do swojego CommunicationUtilities. Racja, nie możesz. Dlatego jest zepsuty.

Arseni Mourzenko
źródło
Cześć MainMa, więc jeśli dobrze rozumiem, właściwe jest utworzenie klasy powiedzenia w tle ze wszystkimi potokami, a następnie wyodrębnienie jej za pomocą interfejsu i przekazanie interfejsu do funkcji zamiast bezpośredniego wywoływania z klasy jak w pierwszym fragmencie.
user60812,
1
@ user60812: w skrócie przeczytaj o IoC. Trudno byłoby wyjaśnić cały temat w prostym komentarzu.
Arseni Mourzenko
1
A co z naprawdę ogólną funkcją narzędzia, taką jak obcinacz łańcuchów?
jbyrd
2
@MainMa - przepraszam, nie śledzę. To jest zgodne z tym, czego chcę, tak. Ale Truncate () nie jest wbudowany w c #, więc zastanawiałem się, czy sensowne byłoby umieszczenie tego rodzaju ogólnej funkcji narzędzia w jakiejś klasie narzędzi.
jbyrd
2
Ta odpowiedź definiuje problem, zauważając, że w tym konkretnym przypadku nie jest wymagana klasa util. Ale generalnie zawsze istnieją pewne metody w stylu „pomocnika”, które nigdzie nie pasują.
usr
9

Pytanie jest prawidłowe, nawet jeśli podany przykład nie jest. Odpowiedź udzielona przez Mainę jest idealna, w bardzo specyficznym kontekście, który nie jest dla mnie odpowiednim kontekstem dla wspomnianych klas „użytkowych” .

Osobiście tworzę folder, Helpersw którym umieszczam proste funkcje do wywoływania z dowolnego miejsca, takie jak rozszerzenia, w którym to przypadku tak, są one statyczne.

Teraz, jeśli istnieje lepszy sposób, chętnie się nauczę, ale jak dotąd:

  • Nie widzę nic złego w rozszerzeniach.
  • Nie widzę nic złego w grupowaniu ich w określonym folderze.

Teraz rozszerzenie to tylko cukier składniowy, równie dobrze może być klasyczną funkcją.

Bernard G.
źródło
6

Żadna z podanych wcześniej odpowiedzi nie dotyczy rzeczywistego pytania. user60812 po prostu zapytał, gdzie należy umieścić klasę użyteczności w projekcie MVC. Wszyscy podeszli do pojedynczego przykładu i narzekali na wszystko oprócz pytania.

@ user60812, w zależności od pożądanego poziomu abstrakcji:

  • A) Utwórz folder i utwórz klasę narzędzia w tym folderze
  • B) Stwórz projekt do przechowywania klas użytkowych (zakładając chęć ponownego użycia zestawu).
  • C) Ekstrapoluj swoje narzędzia do architektury usług i zawołaj do nich

Oto link do podobnego pytania z lepszymi odpowiedziami.

moim zdaniem

Spencer Sullivan
źródło
1

Nie twórz klas statycznych dla narzędzi. W większości przypadków statyka jest zła. Nie nazywaj ich także menedżerami. Cokolwiek nad tym pracujesz, powinno być umieszczone w logicznej przestrzeni nazw.

Na przykład:

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

Adres e-mail, temat i treść to osobna kwestia, dlatego miałbym do tego strukturę klas, dlatego użyłem tego Email emailw powyższym przykładzie.

CodeART
źródło
Proszę wyjaśnić, dlaczego klasy statyczne nie są w stanie utrzymać metod użyteczności? Jestem naprawdę ciekawy twojego rozumowania.
Spencer Sullivan