CRM 2011 - C# 插件
CRM 2011 - C# PLUGIN
我有一个使用 C# 的 CRM 2011 插件:Synchronus,Post-Operation 和 Not-Sandbox。
无论何时启动,该插件都是第一次正常运行。但我的问题是当我第二次调用插件时(使用其他 GUID),实体将具有第一次调用的值。因此,我没有只是调用的新实体属性,而是拥有旧实体的属性(第一次调用)。这个问题有什么解决办法吗?
请注意,我已经尝试过异步模式并且工作正常,但是我需要在调用 Web 服务后在屏幕上显示错误消息,因此我需要它处于同步模式。
插件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;
}
}
}
当插件 class 包含字段时会发生这种情况。插件 classes 不允许是有状态的,因为它们由 CRM 平台实例化一次,然后重复使用。因此,这些 classes 上的字段不是线程安全的。
检查你的 CRMPluginBase
class。查看方法 base.CheckType<Entity>()
很可能这个 class 有一个包含 IPluginExecutionContext
实例的私有字段。重新设计您的插件库 class 并确保它根本不包含实例字段。
我有一个使用 C# 的 CRM 2011 插件:Synchronus,Post-Operation 和 Not-Sandbox。 无论何时启动,该插件都是第一次正常运行。但我的问题是当我第二次调用插件时(使用其他 GUID),实体将具有第一次调用的值。因此,我没有只是调用的新实体属性,而是拥有旧实体的属性(第一次调用)。这个问题有什么解决办法吗? 请注意,我已经尝试过异步模式并且工作正常,但是我需要在调用 Web 服务后在屏幕上显示错误消息,因此我需要它处于同步模式。
插件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;
}
}
}
当插件 class 包含字段时会发生这种情况。插件 classes 不允许是有状态的,因为它们由 CRM 平台实例化一次,然后重复使用。因此,这些 classes 上的字段不是线程安全的。
检查你的 CRMPluginBase
class。查看方法 base.CheckType<Entity>()
很可能这个 class 有一个包含 IPluginExecutionContext
实例的私有字段。重新设计您的插件库 class 并确保它根本不包含实例字段。