Свойство Synchronization обработчиков событий в SharePoint 2010
Рассмотрим типовую задачу, с которой часто приходиться сталкиваться разработчику порталов на SharePoint. Это задача выставления уникальных разрешений
на элемент списка при добавлении и редактировании элемента.
Один из вариантов решения данной задачи - это использование обработчиков событий, выполняющихся после
добавления или редактирования элемента списка. В терминах объектной модели SharePoint - это переопределение методов ItemAdded и ItemUpdated класса SPItemEventReceiver.
Следует понимать, что в SharePoint 2007 указанные события "После добавления" и "После изменения" всегда асинхронные. Т.е. проброс пользователя с формы добавления/редактирования
элемента к списку элементов и выполнение кода в методе ItemAdded или ItemUpdated происходят независимо друг от друга.
Понятно, что в зависимости от скорости выполнения кода в обработчиках данных событий, могут происходить различные неочевидные ситуации.
Самый простой пример - это отсутствие необходимых разрешений у отредактированного элемента сразу после проброса на страницу с общим списком элементов, т.к. код обработчика события "После изменения" еще выполнялся и не успел всем пользователям выдать корректные разрешения.
Как я уже писал выше, в SharePoint 2007 события ItemAdded и ItemUpdated всегда асинхронные, а события ItemAdding и ItemUpdating, выполняющиеся перед сохранением элемента и, служащие в основном для выполнения различных проверок, всегда синхронные.
В SharePoint 2010 появилось больше гибкости в механизме событий, т.к. в класс SPEventReceiverDefinition было добавлено свойство Synchronization, позволяющее
программно определять является ли обработчик события синхронным или асинхронным.
Т.о. для данной задачи, указывая события ItemAdded и ItemUpdated быть синхронными, мы избегаем некорректных ситуаций при выдаче уникальных разрешений на элемент списка и гарантируем, что в начале выполнится код обработчика события и только после его завершения будет выведена страница со списком элементов.
Ниже приведен пример кода, демонстрирующий задание свойства Synchronization класса SPEventReceiverDefinition при активации фичи.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
// полное имя сборки с классом обработчиков событий
string asmName = "ProjectName,Version=1.0.0.0,Culture=neutral,PublicKeyToken=79854f30b071a911";
SPWeb web = (SPWeb)properties.Feature.Parent;
SPList lst = web.GetList(web.Url + "/Lists/TestList");
// полное имя класса с обработчиками событий
string listReceiverName = "ProjectName.EventHandlers.TestListEventReceiver";
// привязка обработчиков событий к списку TestList
SPEventReceiverDefinition eventReceiverUpdated = lst.EventReceivers.Add();
// обработчик будет СИНХРОННЫМ
eventReceiverUpdated.Synchronization = SPEventReceiverSynchronization.Synchronous;
eventReceiverUpdated.Type = SPEventReceiverType.ItemUpdated;
eventReceiverUpdated.Assembly = asmName;
eventReceiverUpdated.Class = listReceiverName;
eventReceiverUpdated.Update();
lst.Update();
SPEventReceiverDefinition eventReceiverAdded = lst.EventReceivers.Add();
eventReceiverAdded.Synchronization = SPEventReceiverSynchronization.Synchronous;
eventReceiverAdded.Type = SPEventReceiverType.ItemAdded;
eventReceiverAdded.Assembly = asmName;
eventReceiverAdded.Class = listReceiverName;
eventReceiverAdded.Update();
lst.Update();
}
|