|  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. Спасибо за помощь еще раз.
		 | 
|  | 
|  | 
| 
 |