1
votes

I have a CRM 2011 plugin using C#: Synchronus, Post-Operation and Not-Sandbox. Whenever launched, the plugin works fine for the first time. But my problem is when I call the plugin the second time (with other GUID), the entity will have the first calling's values. So instead of having the new entity attributes that im just calling, im having the old entity's attributes (first call). Is there any solution to this problem? Note that I have tried the Async mode and it worked fine, but I need to display error messages on the screen after calling a Webservice so I need it to be on Sync mode.

Plugin CLass:

 namespace FNBChangeCustomerInfGroup
{
public abstract class Plugin : IPlugin
{
    public IServiceProvider _serviceProvider;
    public IOrganizationServiceFactory _organizationServiceFactory;
    public IPluginExecutionContext _pluginExecutionContext;
    public IOrganizationService _organizationService;
    public ResourceManager _resourceManager;
    public Lazy<Helper> _helper;

    public IPluginExecutionContext PluginExecutionContext
    {
        get
        {
            if (_pluginExecutionContext == null)
            {
                _pluginExecutionContext = _serviceProvider.GetService(typeof(IPluginExecutionContext)) as IPluginExecutionContext;
                if (_pluginExecutionContext == null)
                {
                    throw new InvalidOperationException("Cannot get Execution Context");
                }
            }
            return _pluginExecutionContext;
        }
    }

    public IOrganizationServiceFactory OrganizationServiceFactory
    {
        get
        {
            if (_organizationServiceFactory == null)
            {
                _organizationServiceFactory = _serviceProvider.GetService(typeof(IOrganizationServiceFactory)) as IOrganizationServiceFactory;
                if (_organizationServiceFactory == null)
                {
                    throw new InvalidOperationException("Cannot get Service Factory");
                }
            }
            return _organizationServiceFactory;
        }
    }

    public IOrganizationService OrganizationService
    {
        get
        {
            if (_organizationService == null)
            {
                _organizationService = OrganizationServiceFactory.CreateOrganizationService(_pluginExecutionContext.UserId);
                if (_organizationService == null)
                {
                    throw new InvalidOperationException("Cannot get Organization Service");
                }
            }
            return _organizationService;
        }
    }

    protected virtual ResourceManager ResourceManager
    {
        get
        {
            if (_resourceManager == null)
            {
                _resourceManager = new ResourceManager(Constants.File_Resources, Assembly.GetExecutingAssembly());
                if (_resourceManager == null)
                {
                    throw new InvalidOperationException("Cannot access Resources file");
                }
            }
            return _resourceManager;
        }
    }

    protected Lazy<Helper> Helper
    {
        get
        {
            if (_helper == null || !_helper.IsValueCreated)
            {
                _helper = new Lazy<Helper>(() => new Helper(_organizationService));
            }
            return _helper;
        }
    }


    public IExtensibleDataObject CheckType<ExtensibleDataObjectType>(string entityLogicalName) where ExtensibleDataObjectType : IExtensibleDataObject, new()
    {
        // Check if the input parameters property bag contains a target
        // of the operation and that target is of type EntityReference.
        if (PluginExecutionContext.InputParameters.Contains(Constants.InputParameter_Target) && PluginExecutionContext.InputParameters[Constants.InputParameter_Target] is ExtensibleDataObjectType)
        {
            // Obtain the target business entity from the input parameters.
            IExtensibleDataObject entity = (PluginExecutionContext.InputParameters[Constants.InputParameter_Target]) as IExtensibleDataObject;

            // Verify that the entity represents a risk carrier quote.

            if (typeof(Entity).IsAssignableFrom(typeof(ExtensibleDataObjectType)))
            {
                if (!String.Equals(((Entity)entity).LogicalName, entityLogicalName)) { return null; }
            }
            else if (typeof(EntityReference).IsAssignableFrom(typeof(ExtensibleDataObjectType)))
            {
                if (!String.Equals(((EntityReference)entity).LogicalName, entityLogicalName)) { return null; }
            }

            return entity;
        }
        else
        {
            return null;
        }
    }

    public virtual void Execute(IServiceProvider serviceProvider)
    {
        this._serviceProvider = serviceProvider;
    }
}

}

1
Most likely you are using instance variables. Post a stripped down version of your code (without webservice calls etc.).Filburt
Entity entity = (Entity)base.CheckType<Entity>(bsynchro_changecustomerinfgroup.EntityLogicalName‌​) This statement is returning the old entity's attributes @FilburtSako Seukunian
Post code in initial message editing it. At the moment your code is not readable.Andrew Butenko
@Micky Entity entity = (Entity)base.CheckType<Entity>(bsynchro_changecustomerinfgroup.EntityLogicalName‌​‌​) This statement is returning the old entity's attributesSako Seukunian
@AndriiButenko Ok you can check nowSako Seukunian

1 Answers

2
votes

This is what happens when a plugin class contains fields. Plugin classes are not allowed to be stateful, because they are instantiated once by the CRM platform and then reused. Therefore fields on these classes are not thread safe.

Check your CRMPluginBase class. Looking at method base.CheckType<Entity>() chances are this class has a private field holding an IPluginExecutionContext instance. Redesign your plugin base class and make shure it does not contain instance fields at all.