вторник, 29 апреля 2008 г.

40 строк кода

Когда последний раз Вы вынуждены были разбираться в ужасном коде?
Когда последний раз Вы писали ужасный код?

Не дадим этому повториться!
Повесьте у себя новый постер - "40 LOC", Вы и Ваши коллеги должны быть предупреждены

Предупреждающий постер
Предупреждающий постер

Он есть в формате Word:
И есть в pdf:
Желающие могут изменить число строк или дополнить текст мотивационными междометиями

P.S. LOC = lines of code, число строк кода. Небольшой LOC у методов является следствием хорошей практики программирования

вторник, 22 апреля 2008 г.

SPWeb.Dispose и SPSite.Dispose

Sharepoint от стека лежащих под ним .net-технологий отличает интересная особенность:
разработчики объектной модели решили не слишком заморачиваться с написанием удобных классов и возложили обязанности по
освобождению памяти
, выделяемой глубоко в недрах Microsoft.Sharepoint.dll native-кодом, на прикладного разработчика.

Если вы используете объектную модель Sharepoint, после использования объектов классов SPWeb и SPSite вы обязаны вызывать у них Dispose-методы, иначе приложение будет терять память.

SPSite oSPSite =newSPSite();
...
oSPSite.Dispose();

Несоблюдение этого правила в большинстве случаев приведет к регулярному перезапуску IIS Worker processes, что негативно сказывается на производительности портала.
Если излишне полагаться на объектную модель, возможно и такое: недавно я видел как метод, выполняющий большую, по сути транзакционную операцию над данными на узле Sharepoint, падает с OutOfMemoryException. Причина - частое создание SPWeb-объектов без освобождения ресурсов.

Основные случаи освобождения памяти описаны в многостраничном Best Practices: Using Disposable Windows SharePoint Services Objects, но информации в нем недостаточно.

Roger Lamb описал ещё 16 ситуаций, в которых безобидные вызовы вроде SPList.BreakRoleInheritance, приводят к утечке памяти.

P.S. статью Roger Lamb я увидел в блоге Serge Luca

воскресенье, 13 апреля 2008 г.

Хранение паролей в .config-файлах

Проблема, о которой я слышу слишком часто - защищенное хранение паролей в .config-файлах.

Стандартное решение для неё - System.Configuration.SectionInformation.ProtectSection() шифрует всю указанную Config-секцию, что не всегда удобно. Да и писать свои кастомные секции хочется не всегда.

John Galloway написал отличную статью о хранении паролей и прочей закрытой информции в .config-файлах приложения. В ней предлагается напрямую использовать DPAPI - технологию, скрытую за вызовами ProtectSection (если используется DpapiProtectedConfigurationProvider).

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

DPAPI - Data Protection API, встроенный в Windows набор вызовов, позволяющий шифровать хранимую информацию 320-битным ключом, уникальным для пользователя. В .net framework эти вызовы выставлены в классе System.Security.Cryptography.ProtectedData, который мы и будем использовать.

Класс, ответственный за шифрование конфигурационных строк:

/// <summary>
    /// Служит для защиты пользовательских секретов, хранимых в .config-файлах 
    /// и других уязвимых источниках 
    /// Для компиляции понадобится подкючить System.Security
    /// </summary>
    class SecureConfigStringProvider
    {
 
        static byte[] entropy = System.Text.Encoding.Unicode.GetBytes("Salt Is Not A Password");
 
        /// <summary>
        /// Шифрует строку уникальным для пользователя ключом        
        /// </summary>        
        /// <returns>Зашифрованная строка в base64</returns>
        public static string EncryptString(string input)
        {
            byte[] encryptedData = System.Security.Cryptography.ProtectedData.Protect(
                System.Text.Encoding.Unicode.GetBytes(input),
                entropy,
                System.Security.Cryptography.DataProtectionScope.CurrentUser);
            return Convert.ToBase64String(encryptedData);
        }
 
        /// <summary>
        /// Расшифрует строку, зашифрованную EncryptString
        /// </summary>
        /// <param name="encryptedData">Зашифрованная строка в base64</param>
        /// <returns>Расшифровання строка</returns>
        public static string DecryptString(string encryptedData)
        {
            try
            {
                byte[] decryptedData = System.Security.Cryptography.ProtectedData.Unprotect(
                    Convert.FromBase64String(encryptedData),
                    entropy,
                    System.Security.Cryptography.DataProtectionScope.CurrentUser);
                return System.Text.Encoding.Unicode.GetString(decryptedData);
            }
            catch
            {
                return "";
            }                       
        }
    }


Его использование для хранения пароля в .config-файле:

Сохраняем пароль:
AppSettings.Password = EncryptString(PasswordTextBox.Password);


После чего он в файле выглядит примерно вот так:

<setting name="Password" serializeAs="String">

<value>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAV......</value>

</setting>



Читаем пароль из файла:
string password = DecryptString(AppSettings.Password);


Этот подход хорошо работает как для windows-приложений, так и для asp.net предложений. Одно неудобство, привязка к одному и тому же пользователю, вероятно помешает его использовать в asp.net-приложении на ферме серверов.

P.S. в оригинальной статье используется SecureString для "безопасной" работы с паролями, но безопасности такое использование не добавляет, а только раздувает код. Поэтому я привел свой вариант вызвовов EncryptString/DecryptString.

четверг, 10 апреля 2008 г.

Классические ошибки - постер

Мой предыдущий пост о классических ошибках подтолкнул меня к оформлению списка в несколько другой форме.
Я внимательно перечитал оригинал, скорректировал некоторые неточности в моём переводе, и уместил список на один лист в Microsoft Word :)

Получившийся постер уже висит у меня на рабочем месте:

Эффект возрастет, когда я перепечатаю его на более плотной бумаге в формате A3/A2 :)

Скачать его можно здесь.
Мне кажется, следущий шаг после распечатки - начать отмечать ошибки, которые происходят в вашем проекте, по мере их обнаружения. Кружочками или палочками.
Я этого не пока не сделал, иначе список на фотографии потерял бы слишком много первозданной белизны :)

P.S. Если результат работы автора и переводчика вам не равнодушен - оставьте свои комментарии и помогите Стиву с составлением нового
"Classic mistakes enumerated".

вторник, 1 апреля 2008 г.

Yellow Drum Machine

Секретные разработки Вооруженных Сил Ямайки!
Автономный робот-барабанщик:

Yellow Drum Machine

Увидено на http://jwz.livejournal.com/