Dynamics CRM - Plug-in Class 和 Workflow Class 的用法与区别
在 Dynamics CRM 开发中,我们可以使用 JavaScript 在前端对 Entity Form 进行数据操作,与此同时,我们也可以使用 C# 写后台插件,其中就包括了 Plug-in Class 和 Workflow Class,如下图所示,这里也简单阐述下两者在使用上的区别:
图1 Plug-in Class 和 Workflow Class
一、调用范围:
Plug-in Class 是在对 Entity 的创建(Create)和更新(Update)时进行调用,而 Workflow Class 是在 Business Process Flow (BPF) 的 workflow 组件里进行调用。
二、使用方式:
Plug-in Class:
编写程序 -> 编译程序集,得到 dll -> 打开 PluginRegistration.exe(路径:SDK 安装目录 > Tools > PluginRegistration)-> 连接 CRM Server -> 选择要部署的 Organization -> 注册 Assembly -> 注册 Step(Create/Update -> Pre-operation/Post-operation) -> 注册 Image(可选,PreImage/PostImage)
完成以上注册后就可以在 CRM 上被调用了。
图2.1 注册 Plug-in 程序集
Workflow Class:
编写程序 -> 编译程序集,得到 dll -> 打开 PluginRegistration.exe -> 连接 CRM Server -> 选择要部署的 Organization -> 注册 Assembly
在注册完 Workflow 程序集后,将 dll 包装在 workflow 组件中,提供给 BPF 调用。
图2.2 注册 Workflow 程序集
图2.3 创建 workflow 组件
图2.4 workflow 组件与 BPF
图2.5 在 BPF 中使用 workflow 组件
三、获取 Entity 对象的方式:
Plug-in Class:
Entity entity = (Entity)context.InputParameters["Target"];
Workflow Class:
Entity entity = service.Retrieve(context.PrimaryEntityName, context.PrimaryEntityId, new Microsoft.Xrm.Sdk.Query.ColumnSet(true));
四、代码示例:
Plug-in Class:
using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; using System; namespace CRMPluginProject_Test { public class PluginClass2 : IPlugin { #region Secure/Unsecure Configuration Setup private string _secureConfig = null; private string _unsecureConfig = null; public PluginClass2(string unsecureConfig, string secureConfig) { _secureConfig = secureConfig; _unsecureConfig = unsecureConfig; } #endregion public void Execute(IServiceProvider serviceProvider) { ITracingService tracer = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = factory.CreateOrganizationService(context.UserId); try { //TODO: Do stuff #region 自定义代码 if (context.MessageName.Equals("Create")) { switch (context.Stage) { case 20://创建 plugin step 的时候设置 create Pre-operation CreatePreAction(tracer, context, service, factory); break; case 40://创建 plugin step 的时候设置 create Post-operation CreatePostAction(tracer, context, service, factory); break; default: break; } } else if (context.MessageName.Equals("Update")) { switch (context.Stage) { case 20://创建 plugin step 的时候设置 update Pre-operation UpdatePreAction(tracer, context, service, factory); break; case 40://创建 plugin step 的时候设置 update Post-operation UpdatePostAction(tracer, context, service, factory); break; default: break; } } #endregion } catch (Exception e) { throw new InvalidPluginExecutionException(e.Message); } } #region 自定义函数 private void CreatePreAction(ITracingService tracer, IPluginExecutionContext context, IOrganizationService service, IOrganizationServiceFactory factory) { //创建当前 entity 时,在存到数据库之前调用 Entity entity = (Entity)context.InputParameters["Target"]; } private void CreatePostAction(ITracingService tracer, IPluginExecutionContext context, IOrganizationService service, IOrganizationServiceFactory factory) { //创建当前 entity 时,在存到数据库之后调用 } private void UpdatePreAction(ITracingService tracer, IPluginExecutionContext context, IOrganizationService service, IOrganizationServiceFactory factory) { //更新当前 entity 时,在存到数据库之前调用 } private void UpdatePostAction(ITracingService tracer, IPluginExecutionContext context, IOrganizationService service, IOrganizationServiceFactory factory) { //更新当前 entity 时,在存到数据库之后调用 } #endregion } }
Workflow Class:
using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Workflow; using System; using System.Activities; namespace CRMPluginProject_Test { public class WorkflowClass1 : CodeActivity { protected override void Execute(CodeActivityContext executionContext) { ITracingService tracer = executionContext.GetExtension<ITracingService>(); IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>(); IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>(); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); try { Entity entity = service.Retrieve(context.PrimaryEntityName, context.PrimaryEntityId, new Microsoft.Xrm.Sdk.Query.ColumnSet(true)); //TODO: Do stuff #region 自定义代码 //通过 workflow 创建一个 task tracer.Trace("Start to create Task"); if (string.IsNullOrEmpty(entity["new_name"].ToString())) { Entities.Task task = new Entities.Task(); task.Subject = "task: " + entity["new_name"].ToString(); task.Description = "try to ceate a task"; task.RegardingObjectId = new EntityReference(entity.LogicalName, entity.Id); service.Create(task); } #endregion } catch (Exception e) { throw new InvalidPluginExecutionException(e.Message); } } } }