|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Нужен совет, на сколько корректно так делать. Есть решение с несколькими проектами: My.Dictionary, My.Shared, My.Book, My.Stored и так далее. Все они содержат свои модели данных для Entity Framework. В Dictionary и Shared при этом некие общие, нужные другим проектам. Теперь для каждого проекта у меня получается свой контекст БД, например для My.Book: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Проблема: теперь в контроллере проекта My.Book я явно должен вызывать создание нужного контекста и передавать его в используемые в этом контроллере репозитории: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
А в вместо такого (проброс контекста через DI): Код: c# 1. 2.
пришлось написать такое (пробрасываем сами опции): Код: c# 1. 2. 3.
Вопрос: нас сколько такая практика приемлема? Или надо делать один общий "ApplicationContext.cs", куда добавлять все DbSet из всех проектов? Описанное выше - попытка сделать контекст БД максимально заточенный для конкретного проекта в решении. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.09.2020, 12:33 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Qwe.Qwe1, В чём смысл разных контекстов? ... |
|||
:
Нравится:
Не нравится:
|
|||
23.09.2020, 13:12 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Идея в том, что, например, каждый проект закреплен за своим разработчиком, он сам делает нужные таблицы в БД, сам управляет контекстом в своем проекте. Возможно еще для чего-то. Если добавить новый проект (аля модуль), то там будет свой контекст. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.09.2020, 14:10 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Qwe.Qwe1 Идея в том, что, например, каждый проект закреплен за своим разработчиком, он сам делает нужные таблицы в БД, сам управляет контекстом в своем проекте. Возможно еще для чего-то. Если добавить новый проект (аля модуль), то там будет свой контекст. Да хоть 100500 разработчиков. Вам не нужно больше одного контекста. Каждый разрботчик может сколько угодно своих моделей добавлять в свой "модуль" и объявлять там класс, реализующий IEntityTypeConfiguration<TEntity>, в контексте не нужно определять свойства для каждой сущности -- это колхоз. Вы всегда можете работать с контекстом через Set<TEntity>(). ... |
|||
:
Нравится:
Не нравится:
|
|||
23.09.2020, 23:32 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
То есть такой общий контекст - это колхоз? А было б удобно, наверно. Его можно через DI в ConfigureServices прокинуть во все контроллеры всех проектов (в решении один из проектов - Asp.Net Web application, а все остальные - ClassLibrary). public class ApplicationContext : DbContext { // Все из проекта My.Dictionary public DbSet<My.Dictionary.Name> Names { get; set; } ... // Все из проекта My.Shared public DbSet<My.Shared.ClassName> ClassNames { get; set; } ... } Тогда что указывать в: Код: c# 1. 2.
>> объявлять там класс, реализующий IEntityTypeConfiguration<TEntity> Ну я так понимаю, такие классы полезны, если есть что конфигурировать с помощью Fluent API, типа такого: builder.ToTable("ClassName").HasKey(p => p.Id); Но свойства DbSet все равно должно же быть в контексте? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 00:07 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Qwe.Qwe1 // Все из проекта My.Dictionary public DbSet<My.Dictionary.Name> Names { get; set; } ... // Все из проекта My.Shared public DbSet<My.Shared.ClassName> ClassNames { get; set; } Это не нужно делать. Данные свойства -- лишние. Qwe.Qwe1 Тогда что указывать в: Код: c# 1. 2.
<AppicationContext> и всё, чего вам ещё нужно-то? :) Один контекст. Qwe.Qwe1 >> объявлять там класс, реализующий IEntityTypeConfiguration<TEntity> Ну я так понимаю, такие классы полезны, если есть что конфигурировать с помощью Fluent API, типа такого: builder.ToTable("ClassName").HasKey(p => p.Id); Но свойства DbSet все равно должно же быть в контексте? Нет, не должны. У вас два варианта по сути: 1. Свойства DbSet в контексте -- колхоз, удобно на мизерных проектах для скорости. 2. IEntityTypeConfiguration<TEntity> и регистрация таких классов со всех сборок. Для модульного решения только 2. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 00:37 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Вот так? В основой проект "WebAppContext.Web" я добавил в зависимости 2 других проекта (Dictionary, Book). А как этот контекст получить в контроллерах этих проектов? В конструкторе надо же указать ApplicationContext, а это не работает: "The type or namespace name 'ApplicationContext' could not be found (are you missing a using directive or an assembly reference?)". Добавить ссылку на проект нельзя - получаются "circular dependency". Вот проект: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 10:33 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Qwe.Qwe1, Посмотрите в сторону modelBuilder.ApplyConfigurationsFromAssembly не обязательно указывать их вручную, также это можно обеспечить через DI и каждый модуль сам может зарегать свои типы ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 10:42 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
А как быть с контекстом? Вот так не работает: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 10:48 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Qwe.Qwe1 А как быть с контекстом? Вот так не работает: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
не совсем понял, что не работает, и что значат вопрсоики в комментарии? присвойте ссылку на контекст приватной переменной и работайте с ней в экшенах. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 10:55 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Qwe.Qwe1, гляньте вот на этот топик: https://stackoverflow.com/questions/59753218/how-to-use-dbcontext-in-separate-class-library-net-core ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 10:56 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Не работает, потому что: "The type or namespace name 'ApplicationContext' could not be found (are you missing a using directive or an assembly reference?)"" Это контроллер не в основном проекте, где и лежит класс "ApplicationContext", а в одном из проектов. И как это исправить? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 10:58 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Qwe.Qwe1, Добавьте ссылку на проект и using для namespace в котором лежит ApplicationContext. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 11:43 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Я уже добавил в основной проект ссылки на 2 других проекта ("модуля"). Теперь если попытаться добавить в проект ("модуль") ссылку на основной проект - будет такая ошибка (я об этом упоминал выше): ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 11:51 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Значит ты сотворил фигню со слоями своего приложения Слой должен зависеть от нижестоящего, и не должен зависеть от вышестоящего. А ты кашу сделал. Начни рисования схемы своего приложения. Скорее всего, тебе нужно контекст вынести в отдельный проект, контекст не должен зависеть от Web ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 11:58 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Shocker.Pro, действительно, если вынести класс с контекстом в отдельный проект, то работает. К вопросу о схеме приложения: чтобы в итоге заработало, пришлось ввести такое ограничение. Проект со словарем, например, разбить на 2: первый хранит данные с моделями и предназначен только для работы с БД. Второй содержит контроллеры, где идет работы со словарем. Не колхоз? ) Вот структура проекта: ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 13:20 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Не зная, что ты подразумеваешь под словарем, ответить на вопрос нельзя. Если ты что-то вынужденно разбил на две части, значит пока еще есть проблемы в архитектуры. Рисуй зависимости модулей друг от друга. Из этого скрина все равно ничего не ясно. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 13:26 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Хорошо, порисую-подумаю на счет разделения. Уже хорошо, что отторжения не вызывает) Да, теперь вместо указания всех сущностей из всех проектов в стиле DbSet<> я пишу для каждой modelBuilder (выше упоминали про возможность рефлексии по сборкам, пока так) и еще и контекст - один класс - в собственно проекте. Надеюсь, что это не вызовет проблем в будущем, например, если реализовывать репозиторий тот же. И еще - контекст содержит все сущности всех проектов, насколько это не утяжеляет его? Не скажется это скорости EF? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 13:47 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Qwe.Qwe1 И еще - контекст содержит все сущности всех проектов, насколько это не утяжеляет его? Не скажется это скорости EF? Не скажется. Регистрируете все конфигурации через DI. Потом из DI достаёте и регистрируете в ApplicationContext. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 14:18 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
hVostt Регистрируете все конфигурации через DI. Потом из DI достаёте и регистрируете в ApplicationContext. А можно пример? Спасибо. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 14:30 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Qwe.Qwe1, Поищите как зарегистрировать все реализации интерфейса (дженерик) из сборки. Затем в модель билдер вытащите все реализации через ServiceProvider и зарегистрируйте их. Так у вас реализация контекста будет неизменной независимо от количество модулей и сборок. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 14:43 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Ок, посмотрю. Но это все направлено на то, чтобы не писать в методе OnModelCreating контекста 10-50-100 строк вида: modelBuilder.ApplyConfiguration(new Dic1Configuration()); а автоматизировать этот процесс? Но в результате, что вручную, что после такой автоматики контекст будет выглядеть одинаково, ведь так? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 14:51 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Qwe.Qwe1 Ок, посмотрю. Но это все направлено на то, чтобы не писать в методе OnModelCreating контекста 10-50-100 строк вида: modelBuilder.ApplyConfiguration(new Dic1Configuration()); а автоматизировать этот процесс? Но в результате, что вручную, что после такой автоматики контекст будет выглядеть одинаково, ведь так? Да, всё верно. Напишите что у вас получилось в результате исследований, я подкорректирую и поправлю если нужно. Мне сейчас сложно дать вам пример, так как я в другом контексте нахожусь ) ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 14:57 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Спасибо, постараюсь в ближайшее время. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 15:03 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
фи, работать с БД в контроллерах. Провайдеры пилите и в них в базу лазьте. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2020, 18:19 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#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 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
hVostt graycode пропущено... Когда доменной логикой является только сохранение данных или их выдача, то доменным слоем становится репозиторий, объект получаемый из репозитория мапится на dto-сущность контроллера, которую контроллер отдает наружу. Доменного слоя не существует :) Объект, получаемый из репозитория, и отдающийся наружу -- это самый примитивный случай, по сути учебный. В реальном мире, необходимо возвращать срез данных, доступных для пользователя для заданного запроса. И ещё ряд различных сценариев, по которым может отработать действие. А выполнение действия должно сопровождаться рядом вырожденных условий. Собственно контроллер от самого названия очевидно должен на требуемый запрос выполнять необходимую логику. А вот это: Код: c# 1.
по сути проксирование и перенос задач контроллера в логику, и протекание логики в контроллер. Так как в таком случае логика пишется 1 в 1 под запросы, что в принципе нарушает SRP. +146 Контроллер задачи аутентификации решает, какие коды http вернуть, в каком формате ответ, что-то логирует из http, какую-то логику сам содержит, мидлваре там ещё работает. Относиться к нему как к прокси над сервисами нижнего слоя - это не прааильно ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2020, 00:54 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
hVostt В реальном мире, необходимо возвращать срез данных, доступных для пользователя для заданного запроса. И ещё ряд различных сценариев, по которым может отработать действие. А выполнение действия должно сопровождаться рядом вырожденных условий. Собственно контроллер от самого названия очевидно должен на требуемый запрос выполнять необходимую логику. Контроллер не должен формировать срез данных или выполнять какую то логику, инициировать работу логики и получить из сформированного среза данных объект который нужно отдать пользователю это задача контроллера, т.е. отмапить полученный срез данных в dto который будет отдан пользователю, если срез данных получить не удалось, то обрабатываются ошибки и тоже формируются объекты для ошибок и отдаются в качестве результата наружу. Логика обрабатывается в более глубоком слое. hVostt А вот это: Код: c# 1.
Сначала должен идти вызов необходимой логики и получение результата, далее если результат получен успешно, то он мапится на SomeModelDtoToReturn и после этого отдается return Ok(SomeModelDtoToReturn), если не получен то создается объект ошибки и выдается вместе со статусом ошибки. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2020, 01:26 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode hVostt В реальном мире, необходимо возвращать срез данных, доступных для пользователя для заданного запроса. И ещё ряд различных сценариев, по которым может отработать действие. А выполнение действия должно сопровождаться рядом вырожденных условий. Собственно контроллер от самого названия очевидно должен на требуемый запрос выполнять необходимую логику. Контроллер не должен формировать срез данных или выполнять какую то логику, инициировать работу логики и получить из сформированного среза данных объект который нужно отдать пользователю это задача контроллера, т.е. отмапить полученный срез данных в dto который будет отдан пользователю, если срез данных получить не удалось, то обрабатываются ошибки и тоже формируются объекты для ошибок и отдаются в качестве результата наружу. Логика обрабатывается в более глубоком слое. hVostt А вот это: Код: c# 1.
Сначала должен идти вызов необходимой логики и получение результата, далее если результат получен успешно, то он мапится на SomeModelDtoToReturn и после этого отдается return Ok(SomeModelDtoToReturn), если не получен то создается объект ошибки и выдается вместе со статусом ошибки. Да. И тестировать это довольно не тривиальное образование как "вызвал что-то там внутри себя" - бессмысленное занятие ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2020, 12:13 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
love_bach graycode пропущено... Контроллер не должен формировать срез данных или выполнять какую то логику, инициировать работу логики и получить из сформированного среза данных объект который нужно отдать пользователю это задача контроллера, т.е. отмапить полученный срез данных в dto который будет отдан пользователю, если срез данных получить не удалось, то обрабатываются ошибки и тоже формируются объекты для ошибок и отдаются в качестве результата наружу. Логика обрабатывается в более глубоком слое. пропущено... Сначала должен идти вызов необходимой логики и получение результата, далее если результат получен успешно, то он мапится на SomeModelDtoToReturn и после этого отдается return Ok(SomeModelDtoToReturn), если не получен то создается объект ошибки и выдается вместе со статусом ошибки. Да. И тестировать это довольно не тривиальное образование как "вызвал что-то там внутри себя" - бессмысленное занятие А если это тупо CRUD, то наварачивать "слои", "провайдеры", "репозитории"... - так себе (просто никому не нужное количество бессмысленного кода). Все нужное можно в самих методах контроллера реализовать ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2020, 12:20 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
love_bach Да. И тестировать это довольно не тривиальное образование как "вызвал что-то там внутри себя" - бессмысленное занятие А кто вас просит писать на это тесты? love_bach А если это тупо CRUD, то наварачивать "слои", "провайдеры", "репозитории"... - так себе (просто никому не нужное количество бессмысленного кода). Все нужное можно в самих методах контроллера реализовать CRUD это репозиторий и есть, хотите превратить контроллер в объект-бог, ваше право. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2020, 13:02 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode love_bach Да. И тестировать это довольно не тривиальное образование как "вызвал что-то там внутри себя" - бессмысленное занятие А кто вас просит писать на это тесты? Я такие тесты не пишу - ответ на это graycode love_bach А если это тупо CRUD, то наварачивать "слои", "провайдеры", "репозитории"... - так себе (просто никому не нужное количество бессмысленного кода). Все нужное можно в самих методах контроллера реализовать CRUD это репозиторий и есть, хотите превратить контроллер в объект-бог, ваше право. "объект-бог" - это несколько про другое, но, пусть будет именно контроллер "богом", если там больше, в конечном итоге, нечему им становиться. Вариант с Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9.
бессмысленный код, который (ладно хрен с ним, легко писать) запаришься читать. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2020, 13:21 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode CRUD это репозиторий и есть... особенно, учитывая, что DbContext - это репозиторий на стероидах от микрософт ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2020, 13:29 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode Контроллер не должен формировать срез данных или выполнять какую то логику, инициировать работу логики и получить из сформированного среза данных объект который нужно отдать пользователю это задача контроллера, т.е. отмапить полученный срез данных в dto который будет отдан пользователю, если срез данных получить не удалось, то обрабатываются ошибки и тоже формируются объекты для ошибок и отдаются в качестве результата наружу. Логика обрабатывается в более глубоком слое. У вас если действия контроллеров 1 к 1 мапятся на методы сервисов, то у вас это не контроллер, а прокси. Вы функции контроллера вынесли и замешали с бизнес-логикой в "более глубоком слое". Года два назад мне упал проект в котором было около 40 контроллеров, и в совокупности чуть более 500 действий контроллеров, которые выглядели так: Код: c# 1. 2. 3. 4. 5. 6. 7. 8.
И таких методов, напомню, более 500 штук. И они продолжали плодиться. Количество оверхеда зашкаливает. Умные люди тупо отказывались работать на этом проекте, ибо говно. Ибо кто-то начитался всякой херни в интернетах, неправильно понял, так и не понял концепции контроллера и заложил такую архитектуру, чтобы люди как можно больше занимались обезьяньим трудом. И да, это всё было обильно покрыто тестами, которые по фидбеку от команды, никогда не ломаются. Никогда, какой бы рефакторинг не проводился, они абсолютно бессмысленные и бестолковые. Вот такие упоротые "орхитекторы" гнездятся тут и там, не желая задействовать даже грамма своего мозга, прежде чем начать работать. graycode Сначала должен идти вызов необходимой логики и получение результата, далее если результат получен успешно, то он мапится на SomeModelDtoToReturn и после этого отдается return Ok(SomeModelDtoToReturn), если не получен то создается объект ошибки и выдается вместе со статусом ошибки. А логика обработки запроса где? Правильно, она у вас переехала в глубокие недра бизнес-логики. И вы ещё рассказываете про SRP. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2020, 16:47 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode CRUD это репозиторий и есть, хотите превратить контроллер в объект-бог, ваше право. А вы с OData работали? Посмотрите, это на многое откроет вам глаза :) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2020, 16:53 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
Прекрасно, только зачем этот ответ был адресован мне? hVostt, love_bach, Все равно мы останемся при своем мнении, сколько бы мы не спорили, поскольку результат будет давать любой подход в том числе и чисто процедурный. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2020, 18:39 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode Ответ адресован вам, но размещён на публичном форуме, т.е. информация нацелена для всех. Никто вас ни к чему не принуждает. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2020, 22:26 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
hVostt Ответ адресован вам, но размещён на публичном форуме, т.е. информация нацелена для всех. Никто вас ни к чему не принуждает. Глупость какая то, отвечать на сообщение но в качестве адресата указывать не то сообщение на которое отвечаете и вообще другого человека, и вы считаете это нормальным? Вот читаю такое сообщение и задаю закономерный вопрос, почему оно было адресовано мне? Хотя наверное "Я такие тесты не пишу - ответ на это", было извинением за ошибку адресом, ну ладно принимается)) ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2020, 00:23 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode hVostt Ответ адресован вам, но размещён на публичном форуме, т.е. информация нацелена для всех. Никто вас ни к чему не принуждает. Глупость какая то, отвечать на сообщение но в качестве адресата указывать не то сообщение на которое отвечаете и вообще другого человека, и вы считаете это нормальным? Вот читаю такое сообщение и задаю закономерный вопрос, почему оно было адресовано мне? Хотя наверное "Я такие тесты не пишу - ответ на это", было извинением за ошибку адресом, ну ладно принимается)) Я ничего не понял. И что за пунктик у вас по этому поводу? :) Мы тут просто общаемся и немного спорим. Считайте, что персональная переписка тут не ведётся. На мой вопрос вам может ответить любой другой из участников, или вступить в дискуссию в любой момент. Вот так всё тут устроено, как в посиделках в хорошей компании. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2020, 01:12 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
hVostt, Ну это совсем беда с логикой, упрощу для вашего понимания, вот напишу я сообщение, а другой человек свои претензии и вопросы по моему сообщению адресует вам, хотя это не ваше сообщение и не совсем ваша позиция, так ситуация понятнее? ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2020, 13:05 |
|
Совет про контекст базы данных - создание в контроллерах
|
|||
---|---|---|---|
#18+
graycode hVostt, Ну это совсем беда с логикой, упрощу для вашего понимания, вот напишу я сообщение, а другой человек свои претензии и вопросы по моему сообщению адресует вам, хотя это не ваше сообщение и не совсем ваша позиция, так ситуация понятнее? Да уж, форумная трагедия, не меньше :) ... |
|||
:
Нравится:
Не нравится:
|
|||
28.09.2020, 01:15 |
|
|
start [/forum/topic.php?all=1&fid=18&tid=1354625]: |
0ms |
get settings: |
10ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
42ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
86ms |
get tp. blocked users: |
2ms |
others: | 12ms |
total: | 184ms |
0 / 0 |