13.03.2013, 10:55 | #1 |
Участник
|
CRM 4.0 Выполнение плагина
Добрый день!
Есть плагин, который выполняется после создания экземпляра кастомной сущности new_grmember, у которой есть атрибут new_groupid. При запуске двух параллельных процессов создания двух различных экземпляров этой сущности с двух разных компьютеров одновременно в алгоритме плагина, запущенного для первого экземпляра, почему-то появляется значение new_groupid из PostImage второго экземпляра. Почему такое может быть? Это какой-то баг или ошибка алгоритма? Текст алгоритма привожу ниже. X++: Guid groupId = ((Lookup)GetEntityProperty("new_groupid")).Value; //------------------// protected object GetEntityProperty(string propertyName) { if (_currentContext.Stage == MessageProcessingStage.AfterMainOperationOutsideTransaction) { if (_postEntityImage == null) _postEntityImage = GetPostEntityImage(_currentContext, TargetEntity.Name); if (_postEntityImage == null) { if (_entity.Properties.Contains(propertyName)) { return _entity[propertyName]; } } else if (_postEntityImage.Properties.Contains(propertyName)) { return _postEntityImage[propertyName]; } return null; } else // (_currentContext.Stage == MessageProcessingStage.BeforeMainOperationOutsideTransaction) { if (!_entity.Properties.Contains(propertyName)) { if (_preEntityImage == null) _preEntityImage = GetPreEntityImage(_currentContext, TargetEntity.Name); if (_preEntityImage == null) return null; else if (_preEntityImage.Properties.Contains(propertyName)) { return _preEntityImage[propertyName]; } return null; } return _entity[propertyName]; } } protected static DynamicEntity GetPostEntityImage(IPluginExecutionContext _currentContext, string _EntityName) { DynamicEntity postImageEntity = null; if (_currentContext.PostEntityImages.Contains(_EntityName)) postImageEntity = _currentContext.PostEntityImages[_EntityName] as DynamicEntity; return postImageEntity; } |
|
13.03.2013, 13:51 | #2 |
Чайный пьяница
|
Покажите пожалуйста кусок кода плагина, где вы объявляете _currentContext, где присваиваете значение.
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством. Подписывайтесь на мой блог, twitter и YouTube канал. Пользуйтесь моим Ultimate Workflow Toolkit Последний раз редактировалось a33ik; 13.03.2013 в 13:51. Причина: Туплю. 4.0 - какая нафиг изоляция. |
|
13.03.2013, 13:55 | #3 |
Участник
|
Цитата:
X++: public abstract class PluginBase : IPlugin { protected DynamicEntity _preEntityImage = null; protected DynamicEntity _entity = null; protected Moniker _moniker = null; protected DynamicEntity _postEntityImage = null; protected string _secureInformation; protected string _unsecureInformation; protected IPluginExecutionContext _currentContext; public PluginBase(string unsecureInfo, string secureInfo) { _unsecureInformation = unsecureInfo; _secureInformation = secureInfo; } public virtual void Execute(IPluginExecutionContext context) { _currentContext = context; } } |
|
13.03.2013, 14:29 | #4 |
Участник
|
protected DynamicEntity _preEntityImage = null;
protected DynamicEntity _entity = null; protected Moniker _moniker = null; protected DynamicEntity _postEntityImage = null; protected IPluginExecutionContext _currentContext; вот этот код необходимо внести в метод Execute из-за этого и проблема. |
|
|
За это сообщение автора поблагодарили: probka (1). |
13.03.2013, 14:33 | #5 |
Участник
|
Цитата:
Сообщение от g.Naukovych
protected DynamicEntity _preEntityImage = null;
protected DynamicEntity _entity = null; protected Moniker _moniker = null; protected DynamicEntity _postEntityImage = null; protected IPluginExecutionContext _currentContext; вот этот код необходимо внести в метод Execute из-за этого и проблема. |
|
13.03.2013, 14:41 | #6 |
Чайный пьяница
|
С вашей проблемой это связано напрямую. Механика плагинов в 4.0 следующая - инстанциируется только один инстанс класса плагина, соответственно все переменные класса - общие для всех запусков, именно поэтому у вас и происходит это перекрывание значений. Переписывайте.
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством. Подписывайтесь на мой блог, twitter и YouTube канал. Пользуйтесь моим Ultimate Workflow Toolkit |
|
|
За это сообщение автора поблагодарили: probka (1). |
13.03.2013, 18:01 | #7 |
Участник
|
Переписала. Не помогло. Скидываю полный текст плагина, может быть, кто подскажет, что я сделала не так.
X++: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Crm.Sdk; using Microsoft.Crm.SdkTypeProxy; using Microsoft.Crm.Sdk.Query; using Microsoft.Win32; using Softline.MsCrm40.Sdk; using Softline.MsCrm40; using Softline.Runov.Apps.Plugins_new.DataAccess; namespace Softline.Runov.Apps.Plugins_new { public class PostCreateGroupMember : Plugin { public PostCreateGroupMember(string unsecureInfo, string secureInfo) : base(unsecureInfo, secureInfo) { } public override void Execute(IPluginExecutionContext context) { try { if (PluginConfiguration.LogIncomingMessages) { Logger.WriteInfo("PostCreateGroupMember Plug-in running.\nPluginExecutionContext:\n" + PluginHelper.GetContextXml(context)); } if (context.CallerOrigin is OfflineOrigin) return; DynamicEntity TargetEntityLocal = (DynamicEntity)context.InputParameters.Properties[ParameterName.Target]; if (context.MessageName == "Create" && TargetEntityLocal.Properties.Contains("new_groupid")) { CreateVisits(context); } UpdateGroupData(context); } catch (Exception ex) { StringBuilder errorMessage = new StringBuilder(); errorMessage.AppendFormat("Plug-in {0} failed\n", this.GetType().ToString()); errorMessage.AppendFormat("PrimaryEntityName: {0}\n", context.PrimaryEntityName); errorMessage.AppendFormat("MessageName: {0}\n", context.MessageName); errorMessage.AppendFormat("Error: {0}\n", ex.Message); InvalidPluginExecutionException invalidPluginExecutionException = new InvalidPluginExecutionException(errorMessage.ToString(), ex); invalidPluginExecutionException.Data.Add("PluginExecutionContext", PluginHelper.GetContextXml(context)); Logger.WriteError(invalidPluginExecutionException); throw invalidPluginExecutionException; } finally { Finally(); } } private void UpdateGroupData(IPluginExecutionContext context) { CrmData crmData = new CrmData(context); GroupMember groupMember = new GroupMember(context); crmData.UpdateGroupData(groupMember.PostGroupId); } /// <summary> /// Создание посещений при добавлении нового обучающегося в группу /// </summary> private void CreateVisits(IPluginExecutionContext context) { Guid groupId = ((Lookup)GetEntityPropertyLocal(context, "new_groupid")).Value; DynamicEntity[] lessons = GroupsDataAccess.RetrieveLessonsByGroup(CrmService, groupId, "new_name", "new_groupid"); DynamicEntity contract = CrmService.RetrieveDynamic("opportunity", ((Lookup)GetEntityPropertyLocal(context, "new_contractid")).Value, "new_numfirstles"); int firstlesson = 0; if (contract.Properties.Contains("new_numfirstles")) { firstlesson = ((CrmNumber)contract["new_numfirstles"]).Value; } Guid GroupMemberIdLocal = (Guid)context.OutputParameters.Properties[ParameterName.Id]; foreach (DynamicEntity lesson in lessons) { string lessonname = lesson["new_name"].ToString(); if (int.Parse(lessonname) >= firstlesson) { VisitsDataAccess.CreateVisit(CrmService, lessonname, ((Key)lesson["new_lessonsid"]).Value, GroupMemberIdLocal); } } } protected object GetEntityPropertyLocal(IPluginExecutionContext context, string propertyName) { DynamicEntity TargetEntityLocal = (DynamicEntity)context.InputParameters.Properties[ParameterName.Target]; if (context.Stage == MessageProcessingStage.AfterMainOperationOutsideTransaction) { DynamicEntity _postEntityImageLocal = GetPostEntityImageLocal(context, TargetEntityLocal.Name); if (_postEntityImageLocal == null) { if (TargetEntityLocal.Properties.Contains(propertyName)) { return TargetEntityLocal[propertyName]; } } else if (_postEntityImageLocal.Properties.Contains(propertyName)) { return _postEntityImageLocal[propertyName]; } return null; } else // (_currentContext.Stage == MessageProcessingStage.BeforeMainOperationOutsideTransaction) { if (!TargetEntityLocal.Properties.Contains(propertyName)) { DynamicEntity _preEntityImageLocal = GetPreEntityImageLocal(context, TargetEntityLocal.Name); if (_preEntityImageLocal == null) return null; else if (_preEntityImageLocal.Properties.Contains(propertyName)) { return _preEntityImageLocal[propertyName]; } return null; } return TargetEntityLocal[propertyName]; } } protected static DynamicEntity GetPreEntityImageLocal(IPluginExecutionContext context, string _EntityName) { DynamicEntity preImageEntity = null; if (context.PreEntityImages.Contains(_EntityName)) preImageEntity = context.PreEntityImages[_EntityName] as DynamicEntity; return preImageEntity; } protected static DynamicEntity GetPostEntityImageLocal(IPluginExecutionContext context, string _EntityName) { DynamicEntity postImageEntity = null; if (context.PostEntityImages.Contains(_EntityName)) postImageEntity = context.PostEntityImages[_EntityName] as DynamicEntity; return postImageEntity; } } } |
|
14.03.2013, 11:07 | #8 |
Участник
|
Как видно из листинга в предыдущем посте, у меня не осталось переменных класса. context определяется при запуске плагина в процедуре Execute. И все равно срабатывает так, как я описала в начале. Подскажите, это не может быть баг CRM?
|
|
14.03.2013, 16:44 | #9 |
Участник
|
Проблема решилась полной перерегистрацией плагина и перезапуском IIS. Спасибо за помощь еще раз.
|
|
|
|