Служебные классы в MVC - ASP.NET

15

Итак, мне было интересно сегодня, где бы вы разместили служебные классы в приложении ASP.NET MVC? Под служебными классами я подразумеваю классы, которые могут быть статическими и просто используются для выполнения функции. Как класс, чтобы отправить электронное письмо, которое принимает адрес электронной почты, тему и тело в качестве аргументов.
Я бы предположил, что, возможно, создание отдельной папки и пространства имен было бы достаточно, но хотел бы узнать мнение каждого.

user60812
источник
3
Зачем создавать служебные классы в любом типе проекта? Почему MVC выделен в вашем вопросе?
Отредактировано
1
Ну, мне было интересно о MVC, потому что это в некотором роде структура сил. А что касается утилиты, у меня сложилось впечатление, что все использовали ее :) Если у меня есть код отправителя электронной почты, и я разделил его на отдельный класс для работы с различными частями системы, не является ли это утилитарным классом или нет? Я был в замешательстве? Я думал, что служебные классы когда-то можно было повторно использовать в любой программе, которая не привязана к коду
user60812
Я бы лично рассмотрел возможность отправки по электронной почте службы, абстрагированной, скажем, от интерфейса IUserNotificationSender или около того ... с надлежащей обработкой ошибок, конфигурацией smtp и т. Д., Которая на самом деле не вписывается в служебную функцию ...
Max
@ Макс так, что бы считать функцию полезности? Я пытаюсь понять, как мне кажется, я очень запутался
user60812 10.09.13
Ну, правильная полезная функция в моем уме - это очень маленькая функция с очень определенной областью действия и без внешних зависимостей ... Например, функция для удаления пробелов, или обрезка строки, или получение n-го элемента коллекции ...
Макс.

Ответы:

11

Вы не И ваш собственный пример является идеальным, чтобы показать, почему нет.

Вы хотите отправлять электронные письма, верно? Таким образом, вы создаете где-то статический класс CommunicationUtilitiesсо статическим SendEmail()в нем. Вы используете этот метод из некоторого класса, который делает кучу вещей, например, сбрасывает пароль пользователя и отправляет ему новый по электронной почте. Отлично.

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

Возможно, вы читали об Inversion of Control, которая имеет преимущество, облегчая модульное тестирование. Статьи о IoC объяснят вам, что вместо того, чтобы делать что-то вроде:

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

ты сделаешь:

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

что позволяет использовать издевательства и заглушки.

Попробуйте применить IoC к вашему CommunicationUtilities. Точно, ты не можешь. Вот почему это сломано.

Арсений Мурзенко
источник
Привет, MainMa, так что, если я правильно понимаю, все еще нужно сделать фоновый класс скажем со всеми трубопроводами, а затем абстрагировать его с помощью интерфейса и передать интерфейс функции вместо прямого вызова из класса, как в вашем первом фрагменте.
user60812 10.09.13
1
@ user60812: короче, читайте про IoC. Было бы трудно объяснить всю тему простым комментарием.
Арсений Мурзенко
1
Как насчет действительно универсальной вспомогательной функции, такой как усечение строк?
Jbyrd
2
@MainMa - извините, я не подписан. Это в соответствии с тем, что я хочу, да. Но Truncate () не встроен в c #, поэтому мне было интересно, имеет ли смысл вставлять такую ​​функцию общего назначения в некоторый класс утилит.
Jbyrd
2
Этот ответ решает проблему, отмечая, что в данном конкретном случае класс утилит не требуется. Но в целом всегда есть некоторые методы стиля «помощника», которые никуда не годятся.
USR
9

Вопрос правильный, даже если приведенный пример - нет. Ответ, данный Майной, идеален в очень специфическом контексте, который не является для меня подходящим контекстом для упомянутых «полезных» классов.

Лично я создаю папку, Helpersв которую помещаю простые функции, которые будут вызываться из любой точки мира, например, расширения, в этом случае, да, они статичны.

Теперь, если есть лучший способ, я буду рад узнать, но пока

  • Я не вижу ничего плохого в расширениях.
  • Я не вижу ничего плохого в группировании их в определенной папке.

Теперь расширение является просто синтаксическим сахаром, оно также может быть классической функцией.

BernardG
источник
6

Ни один из ранее приведенных ответов не относится к актуальному вопросу. user60812 просто спросил, где можно разместить служебный класс внутри проекта MVC. Все послушались единственного примера и побеспокоились обо всем, кроме вопроса.

@ user60812, в зависимости от желаемого уровня абстракции, я бы:

  • A) Создайте папку и создайте служебный класс в этой папке.
  • Б) Создайте проект для хранения служебных классов (при условии повторного использования сборки).
  • C) Экстраполировать ваши утилиты в сервисную архитектуру и вызывать их

Вот ссылка на похожий вопрос с лучшими ответами.

по моему мнению

Спенсер Салливан
источник
1

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

Например:

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

Адрес электронной почты, тема и текст сообщения - это отдельная задача, поэтому у меня для этого будет структура классов, поэтому я и использовал Email emailпример выше.

CodeART
источник
Объясните, пожалуйста, почему статические классы плохо держат служебные методы? Мне искренне любопытно, что вы думаете.
Спенсер Салливан