2

После того, как все ответы на мои последние question about fine-tuning оказались более полезными, чем я ожидал, я подумал, что задам еще один похожий вопрос о MembershipProviders.Как правильно настроить поставщика членства?

Итак, во-первых, чтобы уточнить: я знаю, что такое членство, роль и профиль, как реализовать мои собственные, и как их настроить, и многое из них.
Реализация поставщика роли и профиля довольно проста, потому что в большинстве случаев требуется простой CRUD. (Одной строки LINQ достаточно для примерно половины методов RoleProvider.)

Однако поставщик членства является чужим зверем. Многие из вас могут понять, что это нарушает принцип SR (Single Responsibility), потому что он должен делать ВСЕ, связанное с управлением пользователями. Хотя это оставляет много возможностей для настройки, у него есть свои недостатки. В Интернете нет информации о том, каково их ожидаемое поведение EXACT, например, когда они должны бросать исключения или просто возвращать null, и тому подобное.

Я использую this sample implementation для справки, но он также содержит несколько противоречий.

  • Например, он использует свой собственный метод ValidateUser для проверки учетных данных в методе ChangePassword. Но ValidateUser также обновляет LastLoginDate пользователя до текущей даты. Итак, оправдывает ли рамка, что я установил ее в своем собственном провайдере, или это просто ошибка в выборке?
  • Другое: метод ChangePassword генерирует исключение каждый раз при проверке нового пароля, но CreateUser никогда не генерирует исключение, он просто возвращает false.
  • И последнее, но не менее важное: оно учитывает недопустимые попытки пароля пользователя и блокирует их, если оно проходит порог. Хотя это хорошо, но для его разблокировки требуется ручное действие. Это проблема, если мой провайдер автоматически разблокирует пользователя через определенное время?

  • (EDIT) Я почти забыл: метод CreateUser в образце вставляет идентификатор из параметра метода. Я на самом деле думаю, что это плохая практика, потому что я использую inter с автоматическим сжатием в качестве идентификаторов, поэтому вставка их из некоторого параметра метода не является вариантом. Должен ли я просто игнорировать параметр или требовать, чтобы его значение было null и выдавало исключение, если это не так?

В целом, есть ли в ASP.NET какие-либо предположения о поведении участника-члена?
Есть ли какая-либо документация, которая описывает, когда следует бросать исключение или просто возвращать null?

Я также попытался найти набор универсальных модульных тестов, которые предоставили бы некоторые рекомендации относительно ожидаемого поведения, но не повезло, я нашел много статей о «модульном тестировании» и «Как выполнить модульный тест MembershipProvider », но не тот, где будут какие-либо фактические тесты.

Заранее благодарен всем!

ответ

4

Вы можете проконсультироваться с MSDN для руководства.Например, RoleProvider.RemoveUsersFromRoles предоставляет следующие рекомендации:

RemoveUsersFromRoles вызывается RemoveUserFromRole, RemoveUsersFromRole, RemoveUserFromRoles и RemoveUsersFromRoles методов класса ролей для удаления указанных пользователей из указанных ролей в источник данных. Только роли для настроенного ApplicationName изменены .

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

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

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

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

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

И RoleProvider.GetRolesForUser говорит:

GetRolesForUser называется методом GetRolesForUser класса ролей, чтобы восстановить имена ролей, что указанный пользователь связан с из источника данных. Получены только роли для настроенного имени приложения.

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

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

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

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

Если вы используете отражатель и изучите SqlMembershipProvider, вы заметите некоторые существенные отличия ...

Например:

  • ValidateUser обновления входа в систему даты, потому что, ну, пользователь входа в систему, и он делает это путем вызова .CheckPassword с истинным для UpdateLastLoginTime. Сменить пароль вызывает тот же метод, но отправляет false.

  • Метод CreateUser принимает ProviderUserKey, потому что SPROC также примет параметр UserId. Это позволяет проводить рекреацию и синхронизацию между таблицами членства и пользователей. Как потребитель API, вы обычно не используете эту функциональность, но стек провайдера делает внутренне.

  • Что касается блокировки ... Это зависит от вас. Именно это реализует пользовательские поставщики: получение желаемого поведения. Как я уже сказал, системных требований очень мало.

Таким образом, это приводит нас к последней части вашего вопроса (оба пункта ссылается на то же беспокойство): ожидаемое поведение и модульное тестирование ...

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

В качестве окончательного замечания я предлагаю вам образцы find и download образцов инструментария поставщика Asp.Net. Он предоставляет вам исходный код для полного пакета поставщиков Sql и даст вам некоторое представление о том, как реализуются «реальные» поставщики.

запоздалые мысли:

В этот самый момент я реализует полный SQLite стек провайдера, который 100% совместим со стеком в Sql по умолчанию. Набор тестов проверяет поведенческий паритет между моим стеком и asp.net. Если вы нажмете мой блог через мой профиль и свяжитесь со мной, я дам вам знать, когда тесты будут завершены, и вы можете использовать их в качестве ориентира относительно того, что именно ожидается от стека по умолчанию.

+0

+1. Спасибо за Ваш ответ. Однако вы оставили самую важную часть. В каких методах я должен исключать исключения и в которых должен я просто возвращать false (или null, где это применимо)? – Venemo

+0

@Venemo - Я обновил ответ, чтобы дать вам «официальное» руководство, которое вы просите, а также субъективное руководство. –

+0

Большое спасибо, это именно то, что я искал. :) Я не знал, что у MSDN есть такое окончательное руководство. (О, и я свяжусь с вами в вашем блоге, если вы не возражаете.) – Venemo

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