2011-03-01 4 views
1

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

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

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

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

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

Спасибо.

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

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

ответ

0

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

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

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

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

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

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

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

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

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

+0

Я использую LINQ to SQL и полностью отделяю сущности от контекста, используя [this] (http://linq2sqleb.codeplex.com/) из CodePlex. Другие объекты в этом проекте выполняют условную нагрузку ассоциаций объектов, и это оказалось полным кошмаром. Я не знаю, насколько часто это происходит, но с этого момента я буду избегать этого. Поэтому ... не желая этого решения, я решил удалить ассоциацию от пользователя и создал сущность домена PasswordHistory, чтобы содержать список сущностей DSP UserPassword и связанную с ними логику. При необходимости я использую отдельный запрос для использования этого объекта. – mikesigs

Смежные вопросы