Да, можно. Только в этом случае придется каждый DbSet регистрировать в DI. В случае же передачи DbContext - такой необходимости нет. Кроме того, в случае перехода на DTO, может потребоваться доступ ко всему DbContext, чтобы скомпоновать DTO из нескольких сущностей. И тут одним DbSet уже не обойтись.
Статья в названии имеет слово "подход". То есть, она не описывает готовое решение, которое из коробки подходит для любого случая. Поэтому я не старался сделать репозиторий универсальным.
Если убрать ограничение
where TDbContext : DbContext
то вы сможете передавать любой класс в качестве контекста. Но придется по-другому реализовать свойство DbSet, на котором построен GenericRepository.
A repository is nothing but a class defined for an entity, with all the possible database operations. For example, a repository for an Employee entity will have the basic CRUD operations and any other possible operations related to the Employee entity.
Так что, я считаю, что это, все-таки, репозиторий.
Я объяснил, для чего я решил возвращать IQueryable, чтобы можно было вынести пэйджинг и сортировку в методы расширения, но при этом, выполнять сортировку и выборку страницы на стороне БД.
Повторюсь, что цель проекта была - разработка Web API для админки. Там нет сложных запросов. А вот некоторый поиск и сортировка по столбцам, как это реализовано, например, в ReactAdmin, прекрасно решается предложенным подходом.
Спасибо за комментарий. Если вы дочитали до конца, то там я упомянул, что возможны более сложные случаи, когда отдается DTO, а не доменная сущность. И упомянул, как это решается - вводом маппинга.
В админке обычно отображается то, что лежит в БД. И "куча" кода не будет разрастаться с увеличением количества сущностей (читай таблиц БД). По крайней мере в моей практике, этот подход сработал уже в нескольких случаях. Про валидацию... а я и не заявлял, что опишу как правильно делать валидацию. Показан лишь пример, только подход, который, конечно же, в реальных условиях потребует доработки. И многое оставлено за скобками.
Вот список пакетов, на которые ссылается проект: Microsoft.Extensions.Configuration Microsoft.Extensions.Configuration.EnvironmentVariables Microsoft.Extensions.Configuration.Json Microsoft.Extensions.DependencyInjection Microsoft.Extensions.Options.ConfigurationExtensions
Имелось ввиду, что можно добавить конфигурационные файлы под нужную среду выполнения, хотя я и не показал, как это сделать, но тем не менее. AppSettings - нужен, чтобы использовать механизм IOptions<TOptions> или IOptionsMonitor<TOptions>. Повторюсь, что это лишь пример. В реальном приложении конфигурационных секций, равно как и конфигурационных файлов много больше.
По поводу того, как подключается Startup я спорить не буду, т.к. я не являюсь разработчиком фрэймворка. А вот по поводу размещения инициализации сервисов в модуле program.cs скажу следующее: мне не нравится, когда этот модуль распухает лишь из-за кода, который добавляет в DI необходимые сервисы.
Не очень понял фразу про "полностью наше приложение". В консольном приложении, как и в любом другом, может быть достаточно сложное внутреннее устройство, поэтому использование DI может быть оправдано. Именно для таких случаев и приведен данный пример. По поводу второго замечания - я полностью согласен, убрал построение объектов в методы. Спасибо.
Да, можно. Только в этом случае придется каждый DbSet регистрировать в DI. В случае же передачи DbContext - такой необходимости нет. Кроме того, в случае перехода на DTO, может потребоваться доступ ко всему DbContext, чтобы скомпоновать DTO из нескольких сущностей. И тут одним DbSet уже не обойтись.
Вы правы, по-умолчанию, в случае невалидной модели мы даже не попадем в action-метод. Но это поведение может быть отключено (по разным причинам).
Больше информации можно найти, например, здесь: How to Use ModelState Validation in ASP.NET Core Web API - Code Maze (code-maze.com)
Статья в названии имеет слово "подход". То есть, она не описывает готовое решение, которое из коробки подходит для любого случая. Поэтому я не старался сделать репозиторий универсальным.
Если убрать ограничение
то вы сможете передавать любой класс в качестве контекста. Но придется по-другому реализовать свойство DbSet, на котором построен GenericRepository.
Repository Design Pattern in C# with Examples - Dot Net Tutorials
Так что, я считаю, что это, все-таки, репозиторий.
Не стоит забывать, что описанный подход задуман, как реализация админки, где зачастую, данные отображаются, так, как они хранятся в БД.
В случае, когда generic controller/repository не подходит, можно добавить custom реализацию.
Я объяснил, для чего я решил возвращать IQueryable, чтобы можно было вынести пэйджинг и сортировку в методы расширения, но при этом, выполнять сортировку и выборку страницы на стороне БД.
Повторюсь, что цель проекта была - разработка Web API для админки. Там нет сложных запросов. А вот некоторый поиск и сортировка по столбцам, как это реализовано, например, в ReactAdmin, прекрасно решается предложенным подходом.
А как вы предлагаете без конкретного типа DB-контекста реализовать свойство DbSet?
Спасибо за комментарий. Если вы дочитали до конца, то там я упомянул, что возможны более сложные случаи, когда отдается DTO, а не доменная сущность. И упомянул, как это решается - вводом маппинга.
В админке обычно отображается то, что лежит в БД.
И "куча" кода не будет разрастаться с увеличением количества сущностей (читай таблиц БД). По крайней мере в моей практике, этот подход сработал уже в нескольких случаях.
Про валидацию... а я и не заявлял, что опишу как правильно делать валидацию.
Показан лишь пример, только подход, который, конечно же, в реальных условиях потребует доработки. И многое оставлено за скобками.
Я не добавлял ссылку на этот пакет явным образом.
Вот список пакетов, на которые ссылается проект:
Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.EnvironmentVariables
Microsoft.Extensions.Configuration.Json
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.Options.ConfigurationExtensions
Имелось ввиду, что можно добавить конфигурационные файлы под нужную среду выполнения, хотя я и не показал, как это сделать, но тем не менее.
AppSettings - нужен, чтобы использовать механизм IOptions<TOptions> или IOptionsMonitor<TOptions>.
Повторюсь, что это лишь пример. В реальном приложении конфигурационных секций, равно как и конфигурационных файлов много больше.
Согласен. Исправлю.
Здесь правильно было написать про DI-контейнер.
По поводу того, как подключается Startup я спорить не буду, т.к. я не являюсь разработчиком фрэймворка.
А вот по поводу размещения инициализации сервисов в модуле program.cs скажу следующее: мне не нравится, когда этот модуль распухает лишь из-за кода, который добавляет в DI необходимые сервисы.
Не очень понял фразу про "полностью наше приложение".
В консольном приложении, как и в любом другом, может быть достаточно сложное внутреннее устройство, поэтому использование DI может быть оправдано. Именно для таких случаев и приведен данный пример.
По поводу второго замечания - я полностью согласен, убрал построение объектов в методы.
Спасибо.