Должны ли доменные объекты всегда загружаться целиком? - PullRequest
1 голос
/ 01 марта 2011

У меня есть пользовательский поставщик членства ASP.NET, к которому я пытаюсь добавить функцию истории паролей. Срок действия паролей пользователя истекает через X дней. Затем они должны изменить свой пароль на тот, который не использовался в их прошлых изменениях X.

У меня уже была сущность User, которая имеет атрибут пароля для своего текущего пароля. Это сопоставляется с таблицей User в БД. Поскольку мне требовался список предыдущих паролей, я создал таблицу UserPassword для хранения этой информации со ссылкой FK на UserId.

Поскольку пароли являются объектами-значениями и не имеют никакого значения вне пользователя, они принадлежат совокупности пользователей с пользователем в качестве корня. Но здесь кроется моя дилемма. Когда я получаю пользователя из хранилища, всегда ли мне нужно получать все ранее использованные им пароли? В 99% случаев меня не интересуют их старые пароли, поэтому извлекать их каждый раз, когда мне нужен объект User, кажется глупостью для повышения производительности БД. Я не могу использовать отложенную загрузку, потому что сущность User отключена от контекста.

Я думал о создании объекта PasswordHistory, но по вышеуказанной причине пароли на самом деле не являются объектами.

Как бы вы, эксперты DDD, справились с этой ситуацией?

Спасибо.

Редактировать 1: Обдумав это еще раз, я понял, что это по сути вопрос о отложенной загрузке. В частности, как вы справляетесь с отложенной загрузкой в ​​отключенном объекте?

Редактировать 2: я использую LINQ to SQL. Объекты полностью отделены от контекста, используя this из CodePlex.

1 Ответ

0 голосов
/ 02 марта 2011

Трудно полностью ответить на этот вопрос, потому что вы не указываете платформу, поэтому я не могу точно знать, что вы вообще подразумеваете под «отключенным».С Hibernate «отключен» означает, что у вас есть объект в допустимом сеансе, но соединение с базой данных в настоящее время не открыто.Это тривиально, вы просто переподключаете и ленивый груз.Более сложная ситуация - когда у вас есть объект, который «отсоединен», то есть больше не связан с активным сеансом вообще, и в этом случае вы не можете просто переподключиться, вы должны либо получить новый объект, либо присоединить тот, который у вас есть, кактивный сеанс.

В любом случае, даже в более сложных сценариях стратегии ленивой загрузки по-прежнему не так уж много, потому что требования настолько негибкие: вы должны быть «подключены» для загрузки чего-либо, ленивого илииначе.Период.Я буду считать, что «отключен» означает то же самое, что и «отключен».Ваша стратегия сводится к двум основным сценариям: это ситуация, в которой вам, вероятно, нужно просто повторно подключиться / подключиться к «ленивой» загрузке, или это сценарий, в котором вы хотите принять решение иногда условно загрузить дополнительные объекты перед отключением?во-первых?

Иногда вам может понадобиться код для обеих возможностей.

В вашем случае вам также нужно подключиться не только для ленивой загрузки старых паролей, но и для обновленияПользовательский объект на первом месте.Кроме того, поскольку это ASP.NET, вы можете использовать сеанс для каждого запроса, и в этом случае ваш вариант теперь в основном сводится только к одной - условно-ленивой нагрузке перед вашим отключением, и это все.

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

Тогда всегда есть возможность предоставить им возможность сменить пароль в любое время.Они уже вошли в систему. Здесь не имеет большого значения, у вас есть пользователь, но запрос давно завершен, и на него не загружены пароли.Здесь я, вероятно, просто написал бы метод службы, где при вызове функции смены пароля служба получает вторую копию объекта User с полной историей только для целей обновления, затем обновляет пароль, а затем отбрасывает этот объект, даже неиспользуя его для сеансов или аутентификации.Или, если вы используете Session для запроса, вы должны сделать эквивалентный - получить полностью инициализированный объект для проверки на стороне клиента, тогда, когда данные отправлены, вы можете либо присоединить уже имеющийся, либо просто получить третий экземпляр, чтобы фактическивыполните обновление.

Если после начала аутентифицированного сеанса требуется пароль, вы все равно можете сделать то же самое и заменить локального пользователя или обновить версию пароля в памяти локального пользователя.

Если у вас слишком много работы с несколькими уровнями аутентификации, скорее всего, вам придется потребовать, чтобы они вышли из системы и сделали полный вход в систему после смены пароля, так что состояние пользователяне имеет большого значения, как только они запрашивают смену пароля.

В любом случае, если вы используете сеанс для каждого запроса и ваши объекты становятся полностью отсоединенными после каждого запроса, в первом сценарии вы все равно можете лениво загружаться, пока вы находитесь на сервере по первоначальному запросу, чтобы вернуть данные для проверки на стороне клиента.Во втором сценарии вы должны совершить другое путешествие (здесь действительно нет такой вещи, как ленивая загрузка).В обоих случаях вы должны взвесить два варианта обновления, потому что перед обновлением вы всегда отключены.Вы можете либо просто получить второй экземпляр из базы данных в командировке отправки для обновления, либо снова подключить тот, который у вас уже есть.Это зависит от того, что является оптимальным / самым простым - действительно ли имеет значение сохранение двусторонней базы данных для необычного события?Возможно, повторное присоединение с использованием выбранного вами ORM снова попадет в базу данных?Я, вероятно, не стал бы заново подключать и вместо этого просто получать новый экземпляр для актуального обновления, как мне это нужно.

...