#c# #asp.net-mvc #asp.net-core #asp.net-core-mvc #asp.net-core-5.0
Вопрос:
Допустим, у меня есть контроллер ( UserController
), который содержит около 10 действий ( ListUser, GetUserDetail, SearchUser,...
). Каждое действие будет использовать определенную услугу (одну из IUserListService, IUserDetailService, IUserSearchService,...
). Это службы внедрения зависимостей, которые вводятся из конструктора контроллера.
Проблема в том, что каждый раз, когда мое приложение получает запрос (например /User/ListUser
), выполнение проходит через конструктор контроллера и должно подключать все зависимые службы. Я думаю, что это неэффективно для памяти и производительности, так как оно также подключает ненужные службы вместо подключения только необходимого сервиса: IUserListService
.
- Я не уверен, правильно ли мое предположение или нет?
- Если это правда, существуют ли какие-либо эффективные способы ее решения?
Заранее спасибо.
Комментарии:
1.Видеть docs.microsoft.com/en-us/aspnet/core/mvc/controllers/….
Ответ №1:
Если в конструкторах этих внедренных зависимостей не происходит чего-то дорогостоящего, влияние этих зависимостей на производительность тривиально. Одна из причин заключается в том, что в процессе выполнения запросов используются всевозможные коды. Это включает в себя промежуточное программное обеспечение и всевозможные другие вещи. Создание этих классов не является огромной частью этого.
Возможно, некоторые из этих зависимостей зарегистрированы как синглеты, поэтому они даже не создаются для каждого запроса.
Я не говорю, что производительность и использование памяти абсолютно не вызывают беспокойства (потому что я не могу этого знать), но это маловероятно. Но классы, которые создаются, но никогда не используются, не имеют большого значения. Если есть проблемы с производительностью/памятью, они будут в методах, которые выполняются.
Все это, как говорится, в любом случае, вероятно, стоит разбить эти контроллеры. Если класс имеет десять введенных зависимостей и десять методов, каждый из которых использует разные зависимости, он не является целостным. Все эти десять методов делают совершенно разные вещи, так почему же они все в одном классе?
Класс большой и, вероятно, его трудно поддерживать. Существуют ли модульные тесты для контроллера? Держу пари, что они в классе, который начинается с десяти насмешек. Тесты трудно читать и поддерживать. В результате разработчики будут тратить больше времени на чтение класса и тестов, изменения займут больше времени, и это может привести к дефектам, на исправление которых потребуется время.
Я придумаю несколько цифр, чтобы представить это в перспективе. Они, вероятно, даже близко не похожи на настоящие.
Но предположим, что создание контроллера занимает 3 мс, а уменьшение этих зависимостей означает, что это займет 2 мс, так что вы сэкономили 1 мс. Умножьте это на миллионы запросов, и вы сэкономите 17 минут времени обработки, распределенных по этим миллионам запросов, где они незаметны. С этой точки зрения это может и не иметь значения.
С другой стороны (все еще придумывая это) разделение контроллера может стоить от часа до двух, а затем предотвратить вдвое большее время, затрачиваемое на его чтение, увеличение времени на его обслуживание, дополнительные часы на исправление дефектов и огромные затраты на эти дефекты. Это лучшая причина для того, чтобы разогнать класс.
Комментарии:
1. Спасибо @Scott Hannen, Хотя это не сильно влияет на память/производительность, я все еще думаю, что нехорошо подключать ненужные службы (скажем, у них временный жизненный цикл). Помимо разделения контроллера, как вы думаете, у нас есть другие способы справиться с этим? (В случае, если мы должны хранить все действия пользователя в одном и том же пользовательском контроллере)
Ответ №2:
Если у вас есть контроллер с более чем 4 или 5 интерфейсами, вам следует проверить бизнес-логику. Бывают случаи, когда они необходимы, но в большинстве случаев нет, чтобы разработать более читаемый, изолированный, поддерживаемый и структурированный код. В случае вашего примера, если все интерфейсы связаны с пользователем, у вас должен быть единый интерфейс со всеми функциями, связанными с пользователем. Производительность обычно низкая при обработке больших объемов данных. Например, если вы приводите данные пользователей базы данных, и для этих данных требуется много соединений таблиц, а затем существует бизнес-логика, которая обрабатывает эти данные в памяти, может быть медленной. Я рекомендую вам пересмотреть свой код, чтобы сделать его как можно более кратким, следуя ТВЕРДЫМ принципам, и использовать инструмент проверки производительности для проверки времени выполнения ваших запросов. Например, Минипрофайлер.
Эта информация может помочь вам: https://miniprofiler.com/dotnet/
Комментарии:
1. Спасибо @Facundo, На самом деле, если вы объединяете много интерфейсов в один, вероятно, вы нарушаете «Я» в ТВЕРДОМ ТЕЛЕ.
2. В этом вы правы. В вашем примере я говорил об одном интерфейсе, который концентрирует все функции, связанные с пользователем. У вас не должно быть одного интерфейса для каждого метода.