Введение Зависимостей в классы Модели предметной области с Nhibernate (ASP.NET MVC + МОК)

Я создаю приложение MVC ASP.NET, которое использует DDD (Доменный Управляемый Дизайн) подход с доступом к базе данных, обработанным NHibernate. У меня есть класс модели предметной области (Администратор), в которого я хочу ввести зависимость через Контейнер МОК, такой как замок Windsor, что-то вроде этого:

public class Administrator
{
    public virtual int Id { get; set; }

    //.. snip ..//

    public virtual string HashedPassword { get; protected set; }

    public void SetPassword(string plainTextPassword)
    {
        IHashingService hasher = IocContainer.Resolve<IHashingService>();

        this.HashedPassword = hasher.Hash(plainTextPassword);
    }
}

Я в основном хочу ввести IHashingService для метода SetPassword, не называя Контейнер МОК непосредственно (потому что это, предполагают, чтобы быть Антишаблоном МОК). Но я не уверен, как пойти о выполнении его. Мой объект Администратора через любого инстанцируют new Administrator(); или это загружается через NHibernate, поэтому как я ввел бы IHashingService в класс Администратора?

Поразмыслив, я иду об этом правильным путем? Я надеялся постараться не замусорить свою кодовую базу...

currentAdmin.Password = HashUtils.Hash(password, Algorithm.Sha512);

... и вместо этого заставьте саму модель предметной области заботиться о хешировании и аккуратно инкапсулировать его далеко. Я могу предусмотреть другого разработчика, случайно выбирающего неправильный алгоритм и имеющего некоторые пароли как Sha512 и некоторые как MD5, некоторые с одной солью и некоторые с другой солью и т.д. и т.д. Вместо этого, если разработчики пишут...

currentAdmin.SetPassword(password);

... затем это скрыло бы те детали и заботилось бы о тех упомянутых выше проблемах, будет он нет?

7
задан alexandrul 19 May 2010 в 09:15
поделиться

4 ответа

Здесь уже есть похожие вопросы:

Инъекция зависимости с объектами зависимости с NHIBERNATE объектами

DI / IOBERNATE и помогите в получении их работать вместе

, вам нужно использовать перехватчики. Посмотрите на сообщение Fabio Maulo для реализации:

http://nhforge.org/blogs/nhibernate/archive/2008/12/12/Undities-behavior-Inicive.aspx

5
ответ дан 7 December 2019 в 03:15
поделиться

Я нашел эту страницу, когда пытался сделать то же самое для моего приложения для iPhone, и подумал, что было бы полезно поделиться кодом, на который я решился. Я пытался установить номер базовой версии в моей целевой информации (например, 0.9.5), но затем добавить номер ревизии SVN в конце. Мне это нужно было сохранить в CFBundleVersion, чтобы пользователи AdHoc могли обновлять через iTunes, даже если я не помню, чтобы изменить номер версии на моей панели Целевая информация. Вот почему я не мог использовать метод «revision.h», который в остальном работал красиво. Вот окончательный код, на котором я остановился и который я разместил как этап выполнения сценария сразу после этапа построения «Copy Bundle Resources»:

BASEVERNUM=`/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "${INFOPLIST_FILE}" | sed 's/,/, /g'`
REV=`svnversion -n`
SVNDATE=`LC_ALL=C svn info | awk '/^Last Changed Date:/ {print $4,$5}'`
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BASEVERNUM.$REV" "${TARGET_BUILD_DIR}"/${INFOPLIST_PATH}
/usr/libexec/PlistBuddy -c "Set :BuildDateString $SVNDATE" "${TARGET_BUILD_DIR}"/${INFOPLIST_PATH}

Он должен добавлять результаты svnversion к концу того, что задано в базовом Info.plist в качестве версии. Это путь вы можете иметь что-то вроде 0,9,5 в вашем информационном листе и все еще добавить номер .189 редакции в конце, давая окончательную версию номер 0,9,5,189

Надеюсь, это поможет кому-то еще!

-121--1475609-

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

Можно также попытаться Procdump выгрузить процесс и проанализировать, что действительно произошло на процессоре.

-121--1011272-

Не удается передать IHashingService в конструкторе класса Administrator ? Вот так я бы разрешил зависимость.

public class Administrator
{
    private readonly IHashingService _hashingService;

    public Administrator(IHashingService hashingService)
    {
        _hashingService = hashingService;
    }

    // <snip>

    public void SetPassword(string plainTextPassword)
    {
        this.HashedPassword = _hashingService.Hash(plainTextPassword);
    }
}

Edit # 1

При извлечении из модели попробуйте использовать инъекцию на уровне метода.

public void SetPassword(string plainText, IHashingService hasher)
{
    if (hasher == null) throw new ArgumentNullException("hasher");
    this.HashedPassword = hasher.Hash(plainText);
}

Изменить # 2

Кроме того, почему бы не сделать это проще для себя и просто сделать расширение для последовательности?

public static class ExtensionsOfString
{
    public static string Hash(this string s)
    {
        // hash with SHA256
        return hashedString;
    }
}

Хотя я понимаю, что есть «заменяемый» аспект кода использования инъекции зависимости, это не совсем большое дело для этого примера. Вам на самом деле не нужен IPasswordEncrypureService то же самое, путь вам нужен, скажем, ICredidRuAuthorizationService. Если когда-нибудь вы измените алгоритм хеширования с SHA256 на SHA512, теперь вы потеряете силу каждого пароля в вашей базе данных.

1
ответ дан 7 December 2019 в 03:15
поделиться

Process Explorer - отличный инструмент для поиска и устранения неисправностей. Вы можете попытаться найти проблему высокой загрузки CPU . Это дает вам представление о том, как работает ваше приложение.

Можно также попытаться Procdump выгрузить процесс и проанализировать, что действительно произошло на процессоре.

-121--1011272-

Возвращено ли содержимое bineyData с упаковкой MTOM или двоичные данные только что встроены в сообщение? (Вы можете видеть это в средстве просмотра необработанных ответов в soapUI)

Если это вложение, вы должны иметь соответствующее вложение на вкладке вложений ответов в нижней части окна ответа.

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

с уважением!

/Ole eviware.com

-121--4460415-

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

В противном случае, если вы измените реализацию хэширования по умолчанию, все ваши старые хэшированные пароли перестанут быть хорошими, и ваши пользователи будут оставлены царапать голову о том, почему их пароли больше не работают - и вы получите интерфейс IHashingService , который не обеспечивает гибкости (поскольку реализация хеширования не может быть изменена без добавления странных правил, таких как «use this hash for Administrators created before 2010-01-12»), существующих без реальной причины.

С этой целью я бы добавил соответствующее поле (перечисление, последовательность, возвращенное интерфейсом IHashingService , что-то) и либо предложил NHibernate создать экземпляр службы хеширования для меня через реализацию IUserType , либо я бы использовал заводской образец, где конкретные экземпляры были предоставлены фабрике Это будет сочетать инъекцию на уровне способа Джарретта с решением, которое позволяет регидратированным объектам находить свои реализации хеширования без зависимости от контейнера IoC.

Удачи!

2
ответ дан 7 December 2019 в 03:15
поделиться

Либо хэшируйте пароль на фасаде приложения (если он используется), либо поставьте реализацию IHashingService при каждом вызове на Administrator.SetPassword(...). По-моему, это называлось двойной отправкой ?!

Если вы настаиваете на решении DI-in-entity, я сделал что-то подобное с PostSharp AOP и PostSharp4Spring, объявив атрибут [Configurable] на сущности, но решение для Spring.Net. Вы можете посмотреть здесь для получения дополнительной информации. Также, если вы настраиваете NHibernate из контейнера DI, вы можете попасть в рекурсию, пытаясь DI сущности до того, как контейнер закончит настройку. Вам нужен простой статический класс с методом подавления DI на построение сущностей при инициализации контейнера. Не могу привести пример момента :(

)
1
ответ дан 7 December 2019 в 03:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: