пятница, 28 января 2011 г.

Dependency Injection в SharePoint

Сегодня потребовалось внедрить в проект по SharePoint управление зависимостями.
В качестве инструмента IoC был выбран Ninject.
Внедрение зависимостей в SharePoint дело не простое. Там нет удобной так называемой единой точки входа, которую мы имеем в любом другом решение, которое пишем с нуля (например, ASP.NET-проект, где в нашем распоряжении есть файл global.asax). Кое-какие идеи по внедрению конечно были, но чтобы не изобретать велосипед, решил вначале в интернете посмотреть как люди решают подобную проблему.
Практически сразу наткнулся на статью. Почитал её. На мой взгляд, там нет ничего криминального для SharePoint. Да и к тому же увидел, что человек применил некоторые из моих идей, которые я хотел попробовать. Спасибо ему, что сэкономил моё время.
Попробую на продакшине. Должно работать как часы.
А вы что думаете?

четверг, 27 января 2011 г.

Установка Timeout в сгенерированных DataSet

Добрый день!
В одном из рабочих проектов используем сгенерированные DataSet через XSD-схему, на которую переносятся хранимые процедуры из БД. Как говорится, программа работала отлично до поры до времени. Объем данных вырос и отчеты, использующие эти хранимые процедуры, стали долго строиться (используем ReportViewer) и в конечном итоге вылетать по тайм-ауту. Ясно дело, что надо устанавливать Timeout у SqlConnection. Но лесть в сгенерированный код не хочется, но и не нужно.
Натолкнулся на статью с примером функции расширения:
public static void TableAdapterCommandTimeout(this T TableAdapter, 
        int CommandTimeout) where T : global::System.ComponentModel.Component
{                
    foreach (var c in typeof(T).GetProperty("CommandCollection", System.Reflection.BindingFlags.NonPublic | 
                         System.Reflection.BindingFlags.GetProperty | 
                         System.Reflection.BindingFlags.Instance).GetValue(TableAdapter, null) as 
                         System.Data.SqlClient.SqlCommand[])
        c.CommandTimeout = CommandTimeout;

}
Теперь можно её использовать, например так:
this.FooTableAdapter.TableAdapterCommandTimeout(60);
Медленно конечно будет работать, т.к. через рефлексию сделано, но нам быстро и не надо, т.к. отчеты относительно редко используемые. Да и рефлексия в сравнении со временем, которое нужно для построения отчетов, занимает не так уж много времени.

вторник, 25 января 2011 г.

Явное и неявное преобразование в строку

Тут что-то подумалось. Почему люди так любят вызывать метод ToString() в случаях подобном этому:
int x = 10; 
string str = "Значение = " + x.ToString();
Лично я предпочитаю следующую запись:
string str = "Значение = " + x;
Это удобно для меня во многих случаях. Самый яркий пример: есть коллекция и я пытаюсь получить оттуда значение:
IList<string, int> list = new List<string, int>();
list.Add("key", 10);
string str = "Значение = " + list["key2"]; //Напишет "Значение = "
Если попробовать применить ф-ю list["key2"].ToString(), то получим исключение. Чтобы не было исключений, надо проверять возвращаемое значение из коллекции.
Лично мне кажется это неудобным и поэтому я использую комбинацию:
  • list["key2"] + ""
  • Последующая проверка на string.IsNullOrEmpty(), если нужно.
А вы что думаете?

понедельник, 3 января 2011 г.

Протоколирование. Часть 1.

Всех с наступившим 2011 годом!!! Начнем цикл статей... 

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

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

понедельник, 20 декабря 2010 г.

Автонумерация строк в контролах

Существует очень простой способ декларативно реализовать автонумерацию элементов в контролах:
GridView- <%# Container.DataItemIndex + 1 %>
DataGrid - <%# Container.DataSetIndex + 1 %>
Repeater - <%# Container.ItemIndex + 1 %>
DataList - <%# Container.ItemIndex + 1 %>
Понятно, что это код должен стоять внутри тега <ItemTemplate>

Validator controls + OnClientClick

Сегодня натолкнулся на небольшую проблему: для проверки формы использую валидаторы + небольшой клиентский обработчик. Суть: запретить возврат формы, если не выполняются некоторые условия. Проблема в том, что OnClientClick заменяет собой работа валидатора.
Решение изложено в статье.
Стоит добавить, что ф-я Page_ClientValidate имеет строковый параметр - имя группы валидации. Если его не задать и у вас на странице будет несколько групп валидации, то эта функция будет возвращать false даже, если все корректно заполнено.

среда, 15 декабря 2010 г.

Sharepoint: SPGroup

На просторах интернета наткнулся на очень интересную статью Алексея Садомова про то как создавать новые группы при создании узлов. На самом деле ничего сложного, но новичкам очень полезно для самообучения. Очень может пригодится класс SecurityHelper.

вторник, 14 декабря 2010 г.

Sharepoint: именование полей и списков

Не знаю является ли это ошибкой или это просто удобство, но скажу своё слово. :-)
Очень часто наблюдаю, что начинающие разработчики при создании новых списков и при наделении их полями при именовании сначала сразу же используют русскоязычные названия.
Чтобы была понятна проблема, объясню. Любое поле и список имеет 2 название: внутренние (InternalName) и отображаемое (DisplayName). Когда мы создаем поле или список с русскоязычным названием, то происходит следующее:
  • Список
    • InternalName - присваивается: для обычных списков ListN или для библиотек DocLibN - где N - нумератор списка. Узнается при анализе адресной строки адреса списка.
    • DisplayName - то что ввели
  • Поле
    • InternalName - перекодированное название, что-то наподобие _x041f__x0440__x0438__x0432__x04. Это название можно узнать при анализе адреса, который высвечивается в момент редактирования свойства поля. Там должен быть параметр Field=%5Fx041f%5F%5Fx0440%5F%5Fx0438%5F%5Fx0432%5F%5Fx04. Есть небольшая разница: %5F надо заменить на _ (подчеркивание).
    •  DisplayName - то что ввели
В принципе ничего страшного нет. Но теперь представим "удобство" разработчика, который будет работать с этими объектами. Ужас! Можно конечно статический класс определить с такими полями, но не стоит.
Я придерживаюсь следующего правила:
  • При создании списка/поля вначале называю его по-английски и желательно без пробела (пробел превращается в %20, что тоже на мой взгляд некрасиво). Создается объект с InternalName и DisplayName какой мы задали.
  • Переименовываю объект. InternalName остается какой был. А DisplayName стал более дружественным.
Еще есть одна ошибка, тоже достаточно часто встречающаяся у начинающих разработчиков: при доступе к значениям полей используют DisplayName, например item["Количество"]. Надеюсь понятно почему так делать не стоит? Правильно, DisplayName можно изменить, и тогда наш код перестанет быть рабочим. Правило: всегда стараться использовать в коде InternalName.

Sharepoint: SPContext

При разработке в Sharepoint у нас есть один помощник SPContext - это класс, в котором содержится информация о текущем контексте выполнения кода. Этот класс содержит ряд членов, анализ которых нам может сказать многое. Сам SPContext работает только в рамках портала, т.е. в обработчиках, веб-частях и других элементах, в которых по идеи этот контекст применим. Но этот класс не работает, например, в различных консольных приложениях, т.к. не понятно о каком контексте выполнения может идти речь. Это можно проверить, проанализировав член SPContex.Current. Если программа выполняется вне контекста элементов Sharepoint, то это член равен null.
Что полезного можно вытащить из него? Допустим у нас есть веб-часть, расположенная на какой-нибудь странице портала. Что мы можем увидеть?

Sharepoint: прошлое

Так случилось, что недавно я сменил место работы. На прошлом месте работы я работал со многими платформами от Microsoft, в т.ч. и с Sharepoint. Начал я аж с 2003 версии, а когда увольнялся, то уже как пол-года вышла 2010 версия. Т.о. мне посчастливилось поработать с тремя версиями Sharepoint (2003, 2007 и 2010). От версии к версии Sharepoint становился все более мощным, приятным и тяжелым. В его освоении натыкаешься на ряд проблем, глюков, а местами даже на интересные вещи.
Скажу сразу: программировать под Sharepoint мне нравилось и не нравилось одновременно. Нравилось тем, что это все же платформа и многое уже сделано за нас. И это в свою очередь тоже не нравилось, т.к. хотелось глубже окунуться в мир ASP.NET, но из-за больших проектов это в принципе не получалось, поэтому знание ASP.NET были скорее всего поверхностные. Т.к. Sharepoint построен на технологии ASP.NET, то соответственно его расширение ограничивалось только фантазией. Но дело омрачали периодические возникающие глюки. О некоторых из них я расскажу в следующих статьях.
На новом месте работе опять пришлось столкнуться с Sharepoint и опять я начал вспоминать о глюках Sharepoin, которые возникают то тут то там. Ну раз раньше я их не фиксировал, то теперь уж точно настал момент, чтобы раз и навсегда их зафиксировать и не забыть.
На этом пока всё.

Еще статьи

2leep.com