Корисні класи в MVC - ASP.NET


15

Тож мені було цікаво сьогодні, куди б ви розмістили утилітні класи в додатку ASP.NET MVC? Під класами утиліти я маю на увазі класи, які можуть бути статичними і просто використовуються для виконання функції. Як клас для надсилання електронного листа, який бере аргументи електронної пошти, тему та тіло.
Я б припустив, що, можливо, створення окремої папки та простору імен було б досить добре, але хотів отримати думку всіх


3
Навіщо створювати утилітні класи для будь-якого типу проекту? Чому у вашому запитанні виділено MVC?
Одід

1
Ну, мені було цікаво про MVC, оскільки це певним чином змушує структуру. Що стосується утиліти, то я мав враження, що всі їх використовували :) Якщо у мене є код відправника електронної пошти, і я розділив його на окремий клас для роботи з різними частинами системи, це не клас утиліти чи я Я спантеличений? Я думав, що класи корисних програм були колись багаторазовими для використання в будь-якій програмі, яка не пов'язана з кодом
user60812

Я особисто розглядав би службу надсилання електронною поштою, абстрагувавшись інтерфейсом IUserNotificationSender тощо, з правильним керуванням помилками, конфігурацією smtp і т. Д., Що насправді не входить у функцію утиліти ...
Макс

@Max, що б вважалося функцією корисності? Я намагаюся зрозуміти, як мені здається, я дуже розгублений
user60812

Ну, належна корисна функція в моєму розумі - це дуже мала функція з дуже визначеною сферою дії та відсутністю зовнішніх залежностей ... Наприклад, функція для видалення пробілу, обрізки рядка або отримання n-го елемента колекції ...
Макс

Відповіді:


11

Ви цього не робите. І ваш власний приклад є ідеальним, щоб показати, чому ні.

Ви хочете надсилати електронні листи, правда? Так ви створюєте десь статичний клас CommunicationUtilitiesіз статикою SendEmail()в ньому. Ви використовуєте цей метод з якогось класу, який робить купу матеріалів, наприклад, скидає пароль користувача та надсилає йому новий електронною поштою. Ідеально.

Тепер, що станеться, якщо ви хочете перевірити свій клас? Ви не можете, оскільки кожен раз, коли ви хочете протестувати метод, який скидає пароль, він змінює базу даних (що не підходить для одиничного тестування), а також надсилає електронне повідомлення (що ще гірше).

Ви, можливо, читали про Інверсію управління, яка має перевагу у спрощенні тестування одиниць. Статті про IoC пояснять вам, що замість того, щоб робити щось на кшталт:

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

ви робите:

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

що дозволяє використовувати макети та заглушки.

Спробуйте застосувати IoC до свого CommunicationUtilities. Правильно, ти не можеш. Ось чому він зламаний.


Привіт MainMa, так що якщо я правильно розумію, це правильно все-таки зробити фоновий клас сказати з усіма контурами, а потім абстрагувати його інтерфейсом і передати інтерфейс у функцію замість прямого виклику з класу, як у першому фрагменті.
user60812

1
@ user60812: коротше, читайте про IoC. Було б важко пояснити всю тему простим коментарем.
Арсеній Муренко

1
А як насправді загальна функція утиліти, як струнний магістраль?
jbyrd

2
@MainMa - вибачте, я не стежу за цим. Це так, як я хочу, так. Але Truncate () не вбудований в c #, тому мені було цікаво, чи є сенс дотримуватися такої загальної функції корисності в якомусь класі утиліт.
jbyrd

2
Ця відповідь визначає проблему, зазначивши, що в цьому конкретному випадку не потрібен клас утиліти. Але в цілому завжди є якісь методи "помічників", які ніде не підходять.
usr

9

Питання є правильним, навіть якщо наведений приклад не є. Відповідь, надана Майною, є ідеальною, у дуже специфічному контексті, який не є для мене, належним контекстом для зазначених "корисних" класів.

Особисто я створюю папку, Helpersв яку розміщую прості функції, які потрібно викликати з будь-якого місця, наприклад, розширення, і в цьому випадку, так, вони є статичними.

Тепер, якщо є кращий шлях, я буду радий навчитися, але поки що:

  • Я не бачу нічого з розширеннями.
  • Я не бачу нічого поганого в згрупуванні їх у певну папку.

Тепер розширення - це лише синтаксичний цукор, це також може бути класичною функцією.


6

Жодна з попередньо наданих відповідей не стосується фактичного питання. user60812 просто запитав, де можна розмістити клас корисності всередині проекту MVC. Усі вдарили на єдиний приклад і бігали про все, окрім питання.

@ user60812, залежно від потрібного рівня абстракції, я:

  • A) Створіть папку та створіть клас утиліти у цій папці
  • B) Створіть проект для проведення класів утиліти (припускаючи бажання повторного використання збірки).
  • C) Екстраполюйте свої утиліти в архітектуру сервісу та викликайте їх

Ось посилання на подібне запитання з кращими відповідями.

ІМХО


1

Не створюйте статичні класи для утиліт. Статистика в більшості випадків погана. Не називайте їх також менеджерами. Над чим би ви не працювали, його слід розмістити в логічному просторі імен.

Наприклад:

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

Адреса, тема та адреса електронної пошти - це окрема проблема, тому я маю для цього структуру класів, отже, чому я використовував Email emailу прикладі вище.


Поясніть, будь ласка, чому в статичних класах погано застосовувати корисні методи? Мені справді цікаво ваших міркувань.
Спенсер Салліван
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.