|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
borkes фи, работать с БД в контроллерах. Провайдеры пилите и в них в базу лазьте. Уж лучше в контроллерах, чем пилить какие-то провайдеры ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 19:15 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
love_bach, ну если вы про тестирование не слышали то ОК ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 21:23 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
borkes love_bach, ну если вы про тестирование не слышали то ОК Слышал. Все норм с тестированием. Само название (откуда вы его взяли) "провайдеры" говорит о чем-то странном. Может Вы какой-то смысл не раскрытый в него вкладываете, и за этим стоит что-то нормальное... Но тогда лучше использовать стандартные/общепринятые для этого контекста термины ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 21:50 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
love_bach, ничего странного не вижу. как хотите называете, это просто сущность, которая берёт откуда-то данные - откуда не важно, это интерфейс, реализация которого инжектится. Контроллер это везде и всюду - чисто перезентейшен слой, его задача вернуть резалт, а не делать что-то сложное Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
всё тестирование конт роллера будет в том, чтобы проверить что вызвался get метод провадера, ну а в конкретных провайдерах уже свои тесты, при этом _activePlayersProvider может лазить в какие-то апи, в нескольк баз, мержить данные с глобальным каким-нибудь кэшем, еще чего-то там делать, вы бы это всё в контроллере строчили? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 22:24 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
borkes всё тестирование конт роллера будет в том, чтобы проверить что вызвался get метод провадера, ну а в конкретных провайдерах уже свои тесты, при этом _activePlayersProvider может лазить в какие-то апи, в нескольк баз, мержить данные с глобальным каким-нибудь кэшем, еще чего-то там делать, вы бы это всё в контроллере строчили? Расскажите, в чём смысл этого тестирования? Ваше действие контроллера на примере по сути просто прокси вызова другого метода. Что вы тестируете не пойму? Какая тут сложность кода, которая вдруг может внезапно поломаться при рефакторинге или каких-то изменениях? Какие там вообще могут быть изменения, да и зачем? Собственно из-за такого "тестирования" очень много людей недоумевают нахера оно вообще такое впилось, и зачем этим дол...змом заниматься :) ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 00:07 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
borkes, Работать с БД из контроллера действительно не комильфо, репозитарий обычно отвязывается от контроллера, но провайдер, сколько у вас слоев и разных DTO-шек между сущностью репозитария и сущностью которую отдаете в контроллере? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 00:31 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
hVostt, так в том то и дело, что мой код простой как тапок, потому что он делает одну простую вещь, а именно дергает вызов провайдера, и так как I<ProviderName> это интерфейс, то он легко мокается\стюбится и тд, т.е. покрывается тестами. В реализации этого метода может быть что-то довольно сложное. Если реализация провайдера будет изменена, то это никак не скажется на фунцкионале и тестах контроллера. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 00:39 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode, соглашусь, если данные из бд берутся, то наверно да, лучше звучит термин репозиторий. часто просто данные много с чем замешиваются, что не из бд, я поэтому привык к "провайдерам". модельки к дто-шкам привожу по разному, automapper, ручками, свой маппер пилил однажды. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 00:46 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
borkes и так как I<ProviderName> это интерфейс, то он легко мокается\стюбится и тд, т.е. покрывается тестами. Тесты тут не первичны, первична возможность менять реализацию провайдера. Например можно подменять репозитарий или сторадж не затрагивая все остальное приложение, т.е. можно сменить источник данных с одной СУБД на другую, в том числе нереляционную, просто сменив реализацию репозитория. PS: у автора топика как раз проблема в том что он перемешал классы в кучу и не выделил все что касается репозитария в иерархию отдельных проектов, в результате получил зацикливание зависимостей проектов. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 01:06 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
borkes так в том то и дело, что мой код простой как тапок, потому что он делает одну простую вещь, а именно дергает вызов провайдера, и так как I<ProviderName> это интерфейс, то он легко мокается\стюбится и тд, т.е. покрывается тестами. В реализации этого метода может быть что-то довольно сложное. Если реализация провайдера будет изменена, то это никак не скажется на фунцкионале и тестах контроллера. Тогда какой смысл таких тестов? Понятно что мокается. Чего бы мы там в реализации не меняли, тесты контроллеров всё равно пройдут. Я, если что, намекаю на то, что идея "тонких контроллеров", доведённая до абсолюта -- приводит к бессмысленным действиям и бессмысленному результату. Спрятать весь код в "провайдер" это не более чем замести мусорок под половичок. И собственно оттуда же рождаются всякие вариации на тему OperationResult :) Ну ведь чо, действия контроллера не должны содержать более одной-двух строк, а желательно и вообще не содержать никакого кода ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 01:17 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode PS: у автора топика как раз проблема в том что он перемешал классы в кучу и не выделил все что касается репозитария в иерархию отдельных проектов, в результате получил зацикливание зависимостей проектов. Автору ещё много предстоить усвоить до нормальной архитектуры, и самое главное понять, что идеальной и правильной архитектры и серебряных бест прэктикс не бывает. И что, самое главное, у любой концепции, есть дыры. Это приводит либо к косякам, либо к нафиг не нужному и бессмысленному труду, такому как покрытие тестами контроллеров, которые являются не более чем прокси к жирной логике. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 01:20 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
borkes love_bach, ничего странного не вижу. как хотите называете, это просто сущность, которая берёт откуда-то данные - откуда не важно, это интерфейс, реализация которого инжектится. Контроллер это везде и всюду - чисто перезентейшен слой, его задача вернуть резалт, а не делать что-то сложное Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
всё тестирование конт роллера будет в том, чтобы проверить что вызвался get метод провадера, ну а в конкретных провайдерах уже свои тесты, при этом _activePlayersProvider может лазить в какие-то апи, в нескольк баз, мержить данные с глобальным каким-нибудь кэшем, еще чего-то там делать, вы бы это всё в контроллере строчили? как хотите называете Я бы это назвал "запрос". И, возможно, инкапсулировал как запрос. Или просто в контроллере сделал селект, если там простейший селект из DbContext всё тестирование конт роллера будет в том, чтобы проверить что вызвался get метод провадера Метод контроллера, прежде всего, должен сделать то, что должен сделать согласно своему контракту. А как он это будет делать, "вызвался get метод провадера", или еще как-то - не интересно потребителю контракта. Поэтому для тестирования требуется дернуть этот Get-метод по маршруту active-players с нужными заголовками и убедиться, что он вернул статус 200 (или 403 или еще какой-то) и данные и может еще чего-то. А то, что там что-то мокается... DbContext умеет инмемори... Да и один фиг тестировать запросы надо на БД, а не в инмемори и моках ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 07:43 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode можно сменить источник данных с одной СУБД на другую Когда это можно сделать, не меняя остальное, - репозиторий не нужен. Вернее, той функциональности репозитория, которую предоставляет DbContext, достаточно. Когда это нельзя сделать - репозиторий не поможет graycode ...в том числе нереляционную... ну-ну... ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 07:51 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
hVostt гляньте вот на этот топик: https://stackoverflow.com/questions/59753218/how-to-use-dbcontext-in-separate-class-library-net-core что-то ерунду там советуют - DbContext сам и является UnitOfWork, набрасываешь туда изменений и потом SaveChanges() и это автоматически оборачивается транзакцией hVostt Посмотрите в сторону modelBuilder.ApplyConfigurationsFromAssembly не обязательно указывать их вручную, также это можно обеспечить через DI и каждый модуль сам может зарегать свои типы а можно тут подробней? вот тут есть описание как конфигурить https://www.learnentityframeworkcore.com/configuration/fluent-api#separate-configuration-classes но там метод OnModelCreating защищенный, т.е. * ТС делает сборку MyApp.Context, где базовый контекст без ничего * Делает сборки MyApp.Context.Shared, MyApp.Context.Dic, MyApp.Context.Book и так далее, там во всех он добавляет в зависимости сборку MyApp.Context, получает доступ к базовому контексту с DbSet<T>, и в каждой сборке Shared/Dic/Book делает свой набор IEntityTypeConfiguration<T> * Но он не может их зарегать внутри контекста MyApp.Context, потому что метод OnModelCreating защищенный, т.е. ему надо сначала создать наследника базового контекста и поместить туда ApplyConfigurationsFromAssembly как их туда пропихнуть через DI? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 08:17 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
так что ли? https://dotnetfalcon.com/untitled/ ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 08:24 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
hVostt Я, если что, намекаю на то, что идея "тонких контроллеров", доведённая до абсолюта -- приводит к бессмысленным действиям и бессмысленному результату. Спрятать весь код в "провайдер" это не более чем замести мусорок под половичок. Single Responsibility Principle ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 11:08 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode hVostt Я, если что, намекаю на то, что идея "тонких контроллеров", доведённая до абсолюта -- приводит к бессмысленным действиям и бессмысленному результату. Спрятать весь код в "провайдер" это не более чем замести мусорок под половичок. Single Responsibility Principle Нет, в данном случае это заблуждение. У контроллера гораздо больше задач, чем проксировать вызов в некий сервис. Это, валидация и обработка ошибок, в том числе бизнес-валидация. Кеширование ответов, обеспечение атомарности операции. Вот тогда есть смысл тестировать. Тестируется на вызов метода сервиса, а правильная обработка запроса. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 14:31 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
17-77 что-то ерунду там советуют - DbContext сам и является UnitOfWork, набрасываешь туда изменений и потом SaveChanges() и это автоматически оборачивается транзакцией речь про настройку изоляции, да и любой нужной логики на сохранение. 17-77 а можно тут подробней? вот тут есть описание как конфигурить https://www.learnentityframeworkcore.com/configuration/fluent-api#separate-configuration-classes но там метод OnModelCreating защищенный, т.е. * ТС делает сборку MyApp.Context, где базовый контекст без ничего * Делает сборки MyApp.Context.Shared, MyApp.Context.Dic, MyApp.Context.Book и так далее, там во всех он добавляет в зависимости сборку MyApp.Context, получает доступ к базовому контексту с DbSet<T>, и в каждой сборке Shared/Dic/Book делает свой набор IEntityTypeConfiguration<T> * Но он не может их зарегать внутри контекста MyApp.Context, потому что метод OnModelCreating защищенный, т.е. ему надо сначала создать наследника базового контекста и поместить туда ApplyConfigurationsFromAssembly как их туда пропихнуть через DI? Ну вариантов масса. Можно зарегистрировать все реализации IEntityTypeConfiguration как Transient. Потом получить IEnumerable этих реализации и засунуть в ModelBuilder в DbContext или через построитель опций. Можно сделать диспетчер этих реализаций, чтобы можно было разделить по сборкам. Дофига чего можно сделать :) ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 14:38 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
По сути, если сервис, который использует контроллер возвращает данные, которые напрямую передаются во фронт -- это прямое и жестокое нарушение SRP. И бесполезными тестами тут не отмажешься. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 15:05 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
hVostt Нет, в данном случае это заблуждение. У контроллера гораздо больше задач, чем проксировать вызов в некий сервис. Это, валидация и обработка ошибок, в том числе бизнес-валидация. Кеширование ответов, обеспечение атомарности операции. Вот тогда есть смысл тестировать. Тестируется на вызов метода сервиса, а правильная обработка запроса. Не соглашусь, задача контроллера получить/выдать данные данные и запустить дальнейший процесс их обработки если она требуется, валидацию и обработку ошибок контроллер должен осуществлять на своем слое, а это слой dto-сущностей контроллера, бизнес валидация в зоне ответственности слоя реализующего основную бизнес-логику, в этом случае репозиторий будет также отдельным слоем и по отношению к слою реализующему доменную логику, репозиторий будет оперировать dto-ками только своими. Тестирование правильной обработки запроса в целом не является задачей модульного тестирования. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 18:53 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
hVostt По сути, если сервис, который использует контроллер возвращает данные, которые напрямую передаются во фронт -- это прямое и жестокое нарушение SRP. И бесполезными тестами тут не отмажешься. Когда доменной логикой является только сохранение данных или их выдача, то доменным слоем становится репозиторий, объект получаемый из репозитория мапится на dto-сущность контроллера, которую контроллер отдает наружу. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 18:58 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode hVostt Нет, в данном случае это заблуждение. У контроллера гораздо больше задач, чем проксировать вызов в некий сервис. Это, валидация и обработка ошибок, в том числе бизнес-валидация. Кеширование ответов, обеспечение атомарности операции. Вот тогда есть смысл тестировать. Тестируется на вызов метода сервиса, а правильная обработка запроса. Не соглашусь, задача контроллера получить/выдать данные данные и запустить дальнейший процесс их обработки если она требуется, валидацию и обработку ошибок контроллер должен осуществлять на своем слое, а это слой dto-сущностей контроллера, бизнес валидация в зоне ответственности слоя реализующего основную бизнес-логику, в этом случае репозиторий будет также отдельным слоем и по отношению к слою реализующему доменную логику, репозиторий будет оперировать dto-ками только своими. Тестирование правильной обработки запроса в целом не является задачей модульного тестирования. Как-то всё в кучу смешано, вроде здравое зерно просматривается, но какой-то поток сознания ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 20:08 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode hVostt По сути, если сервис, который использует контроллер возвращает данные, которые напрямую передаются во фронт -- это прямое и жестокое нарушение SRP. И бесполезными тестами тут не отмажешься. Когда доменной логикой является только сохранение данных или их выдача, то доменным слоем становится репозиторий, объект получаемый из репозитория мапится на dto-сущность контроллера, которую контроллер отдает наружу. Сохранение/извлечение сущности (данных) - это не "доменная логика". Это за пределами зоны ответственности домена, и вообще это не логика. Да и домена может не быть (тупо CRUD) ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 20:58 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode Не соглашусь, задача контроллера получить/выдать данные данные и запустить дальнейший процесс их обработки если она требуется, валидацию и обработку ошибок контроллер должен осуществлять на своем слое, а это слой dto-сущностей контроллера, бизнес валидация в зоне ответственности слоя реализующего основную бизнес-логику, в этом случае репозиторий будет также отдельным слоем и по отношению к слою реализующему доменную логику, репозиторий будет оперировать dto-ками только своими. Ну как же. В вашем примере вы возвращаете 200 ОК с данными, полученными из логики. При чём тип данных тот же, логика протекает в контроллер. А где остальные ситуации? Запрос отсутствующих данных? Некорректные данные запроса? Ошибка выполнения логики? Кеширование? И всё остальное -- в чём собственно и есть смысл контроллера. Подходить к архитектуре нужно с пониманием, а не применять их бездумно в лоб. Иначе у вас будет очень много откровенного мусора в коде, ненужных тестов и лишнего обвеса ради обвеса. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 23:51 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode hVostt По сути, если сервис, который использует контроллер возвращает данные, которые напрямую передаются во фронт -- это прямое и жестокое нарушение SRP. И бесполезными тестами тут не отмажешься. Когда доменной логикой является только сохранение данных или их выдача, то доменным слоем становится репозиторий, объект получаемый из репозитория мапится на dto-сущность контроллера, которую контроллер отдает наружу. Доменного слоя не существует :) Объект, получаемый из репозитория, и отдающийся наружу -- это самый примитивный случай, по сути учебный. В реальном мире, необходимо возвращать срез данных, доступных для пользователя для заданного запроса. И ещё ряд различных сценариев, по которым может отработать действие. А выполнение действия должно сопровождаться рядом вырожденных условий. Собственно контроллер от самого названия очевидно должен на требуемый запрос выполнять необходимую логику. А вот это: Код: c# 1.
по сути проксирование и перенос задач контроллера в логику, и протекание логики в контроллер. Так как в таком случае логика пишется 1 в 1 под запросы, что в принципе нарушает SRP. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 23:58 |
|
|
start [/forum/topic.php?fid=18&msg=40002398&tid=1354625]: |
0ms |
get settings: |
9ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
40ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
55ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 154ms |
0 / 0 |