Страницы

Поиск по вопросам

воскресенье, 7 июля 2019 г.

Один DbContext на всё приложение

Во многих мануалах в интернете и в учебнике Фримена для Identity создавался отдельный контекст БД (его даже наследовать надо от специального IdentityDbContext). Я так и пытался сделать в своём проекте, а потом столкнулся со сложностями связывания. Я задал вопросы тут (ruSO и enSO), но решения не последовало.
В связи с этим у меня возник другой вопрос: на сколько нормальной считается практика использовать один контекст БД для всего приложения? (Приложение по функционалу представляет из себя что-то на подобии форума с постами, комментариями и модерацией).
То есть, на сколько нормальным будет считаться подобный один контекст на всё приложение:
public class AppContext : IdentityDbContext { public AppContext(DbContextOptions options) : base(options) { }
public DbSet Forums { get; set; } public DbSet Posts { get; set; } public DbSet Comments { get; set; } public DbSet Attachments { get; set; } //прочие таблицы
protected override void OnModelCreating(ModelBuilder builder) { builder.Entity(ConfigureForum); // forum -> [has many] -> posts builder.Entity(ConfigurePost); // post -> [has one] -> applicationUser; post -> [has many] -> comments builder.Entity(ConfigureComment); // comment -> [has one] -> applicationUser; comment -> [has one] -> parent_comment builder.Entity(ConfigureAttachment);
builder.Entity(ConfugurePostAttachment); builder.Entity(ConfugureCommentAttachment); }
// Описание методов конфигурации }
Каждый пост и комментарий имеет автора в лице ApplicationUser, что и вызывает сложности при разделении контекста.


Ответ

По поводу модульности. Во многих приложениях есть такий принцип, что всё приоложение разделено на независимые модули, которые могут подключаться и отключаться. Каждый модуль реализует какие-то функциональные возможности. Например, на этой картинке

вкладки session, bans, admins, players, manage server и чат - представляют собой отдельные модули, которые могут быть при желании отключены.
Это очень удобно, так как позволяет разбить всю функциональность приложения на небольшие участки, которые легче развивать, поддерживать и заменять. Это таже может быть основой для добавления аддонов (расширений) в приложение. Это касается не только десктоп приложений, но и любых других, например, CMS Orchard, WordPress и тд. Собственно, разделение на модули снижает сложность приложения и даже может увеличить его надежность. Если рассуждать дальше, то для серверных приложений следующий шаг после модульности - переход к микросервисам
Конечно, нужно понимать, что если вы собираетесь писать модульное приложение, то это потребует дополнительных усилий с вашей стороны, так как вам надо будет решить много вопросов по загрузке модулей, их сообщению, необходимости изоляции модулей и тд. Потому писать hello world модульным смысла не имеет.
Что касается контекста данных. Как я уже сказал, верного рецепта нет. Есть только те возможности, что вас устраивают. Если вы хотите сохранить модуль авторизации полностью отделенным от всего остального, то тогда да, вам луше вести 2 контекста данных, и ваша основная логика должна хранить только ту часть информации о юзерах, что для неё требуется. То есть, например, физ адрес юзера, его прдпочтения в еде, его подписки на рассылку - это все та инфа, что не касается авторизации, и её вы можете хранить в основном контексте данных. А вот логин/хеш пароля, счетчик попыток входа, и тд - это в контексте авторизции. Тогда ваши контексты никак не должны пересекаться. (Почитайте также про более широкое понятие контекста - DDD bounded context) И чтобы получить, например, таблицу [логин юзера - подписка] вам придется делать 2 запроса. Сначала получить подписки в виде [ид юзера - подписка] из основного контекста, а потом получить логины юзеров по айдишникам через модуль авторизации [ид юзера - логин юзера], и в памяти уже объединять результаты. Поначалу это кажется излишним, но это сыграет роль, если данные авторизации понадобится хранить в отдельной БД или придется выделить авторизацию в отдельный микросервис, или модуль авторизации надо будет переиспользовать в других проектах. Основной посыл тут - если разделить авторизацию и основную логику, то изменение авторизации не затронет никак основную логику.
Однако, если вы делаете учебный проект, где вы напишете авторизацию 1 раз и никогда уже не будете менять, где вы сделаете контекст данных 1 раз и больше он меняться не будет, где вы не предполагаете никакой модульности и изоляции модулей друг от друга, то тогда разделение контекста данных на 2 вам не даст никакой выгоды, но принесет проблем при поддержке и развитии приложения (с теми же миграциями, например).
То есть каждый из вариантов вам даст какой то профит и при этом даст какие то проблемы. Исходя из этого вам и надо выбрать то решение, что больше вам подходит.

Комментариев нет:

Отправить комментарий