Microsoft Dynamics CRM - 插件


插件是与 Microsoft Dynamics CRM 集成的自定义业务逻辑,用于修改或扩展平台的标准Behave。插件充当事件处理程序并注册以在 CRM 中的特定事件上执行。插件用 C# 或 VB 编写,可以在同步或异步模式下运行。

您编写插件的一些场景是 -

  • 当您创建或更新 CRM 记录时,您希望执行一些业务逻辑,例如更新记录的某些字段或更新相关记录等。

  • 您希望在某些事件(例如保存或更新记录)上调用外部 Web 服务。

  • 您希望在打开任何记录时动态计算字段值。

  • 您希望自动化流程,例如就 CRM 中的某些事件向客户发送电子邮件。

事件框架

CRM 中的事件处理框架通过将同步和异步插件请求传递到事件执行管道来处理同步和异步插件请求。每当事件触发插件逻辑时,就会向 CRM 组织 Web 服务发送一条消息,其他插件或平台的任何核心操作都可以在其中读取或修改该消息。

插件管道阶段

整个插件管道分为多个阶段,您可以在其中注册自定义业务逻辑。指定的管道阶段指示您的插件代码在插件执行周期的哪个阶段运行。在下表中的所有指定管道阶段中,您只能在事件前和事件后注册自定义插件。您无法在 Platform Core Main Operations 上注册插件。

事件 艺名 描述
活动前 预验证 在主系统操作之前执行的插件的管道阶段。在此阶段注册的插件可以在数据库事务之外执行。
活动前 操作前 管道中的阶段,用于在主系统操作之前执行的插件。在此阶段注册的插件在数据库事务中执行。
平台核心运营 主要操作 事务中,系统的主要操作,如创建、更新、删除等。此阶段不能注册任何自定义插件。仅限内部使用。
活动结束后 术后 管道中的阶段,用于在主操作之后执行的插件。此阶段注册的插件在数据库事务内执行。

每当 CRM 应用程序调用事件(例如保存或更新记录)时,都会发生以下操作序列 -

  • 事件触发 Web 服务调用,并通过事件管道阶段(事件前、平台核心操作、事件后)传递执行。

  • 这些信息在内部打包为OrganizationRequest消息,最终发送到内部CRM Web服务方法和平台核心操作。

  • OrganizationRequest 消息首先由事件前插件接收,该插件可以在将信息传递给平台核心操作之前修改信息。平台核心操作完成后,消息被打包为OrganizationResponse并传递给操作后插件。后操作插件可以选择在将其传递给异步插件之前修改此信息。

  • 插件以上下文对象的形式接收此信息,该信息被传递到 Execute 方法,然后进行进一步处理。

  • 所有插件处理完成后,执行将传递回触发事件的应用程序。

插件消息

消息是插件(或业务逻辑)注册的事件。例如,您可以在“创建联系人消息”实体上注册一个插件。每当创建新的联系人记录时,这都会触发业务逻辑。

对于自定义实体,以下是基于实体是用户拥有还是组织拥有的支持的消息。

消息名称 所有权类型
分配 仅限用户拥有的实体
创造 用户拥有和组织拥有的实体
删除 用户拥有和组织拥有的实体
授予访问权限 仅限用户拥有的实体
修改访问权限 仅限用户拥有的实体
取回 用户拥有和组织拥有的实体
检索多个 用户拥有和组织拥有的实体
检索主体访问权限 仅限用户拥有的实体
检索共享主体和访问权限 仅限用户拥有的实体
撤销访问权限 仅限用户拥有的实体
设置状态 用户拥有和组织拥有的实体
设置状态动态实体 用户拥有和组织拥有的实体
更新 用户拥有和组织拥有的实体

对于默认的开箱即用实体,支持的消息超过 100 条。这些消息中的一些适用于所有实体,而其中一些则特定于某些实体。您可以在 SDK 内的 Excel 文件中找到支持的消息的完整列表:SDK\Message-entity support forplug-ins.xlsx

编写插件

在本节中,我们将学习编写插件的基础知识。我们将创建一个示例插件,该插件创建一个任务活动,以便在系统中添加新客户时(即在 CRM 中创建新的联系人记录时)跟进客户。

首先,您需要包含对Microsoft.Xrm.Sdk命名空间的引用。CRM SDK 包含所有必需的 SDK 程序集。假设您已经下载并安装了第2章中的SDK,打开Visual Studio。创建一个类型为类库的新项目。您可以将该项目命名为 SamplePlugins 并单击“确定”。

MSCRM 插件创建与解决方案

将Microsoft.Xrm.Sdk程序集的引用添加到您的项目中。该程序集存在于SDK/Bin中。

Mscrm 插件添加解决方案参考

现在,创建一个名为PostCreateContact.cs的类并从IPlugin扩展该类。到目前为止,您的代码将如下所示。

MSCRM 插件示例代码

您还需要添加对 System.Runtime.Serialization 的引用。添加所需的引用后,将以下代码复制到PostCreateContact类中。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xrm.Sdk;

namespace SamplePlugins {
   public class PostCreateContact:IPlugin {
      /// A plug-in that creates a follow-up task activity when a new account is created.
      /// Register this plug-in on the Create message, account entity,
      /// and asynchronous mode.

      public void Execute(IServiceProviderserviceProvider) {
         // Obtain the execution context from the service provider.
         IPluginExecutionContext context =(IPluginExecutionContext)
            serviceProvider.GetService(typeof(IPluginExecutionContext));

         // The InputParameters collection contains all the data
            passed in the message request.

         if(context.InputParameters.Contains("Target")&&
            context.InputParameters["Target"]isEntity) {
            
            // Obtain the target entity from the input parameters.
            Entity entity = (Entity)context.InputParameters["Target"];
            try {
               
               // Create a task activity to follow up with the account customer in 7 days
               Entity followup = new Entity("task");
               followup["subject"] = "Send e-mail to the new customer.";
               followup["description"] =
                  "Follow up with the customer. Check if there are any new issues
                  that need resolution.";
               
               followup["scheduledstart"] = DateTime.Now;
               followup["scheduledend"] = DateTime.Now.AddDays(2);
               followup["category"] = context.PrimaryEntityName;

               // Refer to the contact in the task activity.
               if(context.OutputParameters.Contains("id")) {
                  Guid regardingobjectid = new Guid(context.OutputParameter
                     s["id"].ToString());
                  string regardingobjectidType = "contact";
                  followup["regardingobjectid"] = 
                     new EntityReference(rega rdingobjectidType,regardingobjectid);
               }
               
               // Obtain the organization service reference.
               IOrganizationServiceFactory serviceFactory =
                  (IOrganizationSer viceFactory)serviceProvider.GetService
                  (typeof(IOrganizationServiceFactory));
               IOrganizationService service = 
                  serviceFactory.CreateOrganizationService(context.UserId);

               // Create the followup activity
               service.Create(followup);
            } catch(Exception ex) {
               throw new InvalidPluginExecutionException(ex.Message);
            }
         }
      }
   }
}

以下是此代码的逐步解释 -

步骤 1 - 通过将 IServiceProvider 对象作为其参数来实现 Execute 方法。服务提供者包含对您将在插件中使用的许多有用对象的引用。

步骤 2 - 使用 IServiceProvider 的 GetService 方法获取 IPluginExecutionContext 对象。

步骤 3 - 从上下文对象的 InputParameters 集合中获取目标实体的对象。该实体类对象引用我们的插件将在其上注册的联系人实体记录。

步骤 4 - 然后创建任务实体的对象并设置适当的主题、描述、日期、类别和相关对象 ID。aboutobjectid 指示正在为哪个联系人记录创建此活动记录。您可以看到代码使用 context.OutputParameters 获取父联系人记录的 id,并将其与您创建的任务实体记录相关联。

步骤 5 - 使用 IServiceProvider 对象创建 IOrganizationServiceFactory 对象。

步骤 6 - 使用 IOrganizationServiceFactory 对象创建 IOrganizationService 对象。

步骤 7 - 最后,使用此服务对象的 Create 方法。它创建保存在 CRM 中的后续活动。

签署插件程序集

本节仅在您首次注册插件程序集时适用。您需要使用密钥登录程序集才能部署插件。右键单击该解决方案,然后单击“属性”。

MSCRM 插件解决方案属性

从左侧选项中选择“签名”选项卡,然后选中“对程序集进行签名”选项。然后,从选择强名称密钥文件选项中选择新建。

MSCRM 插件签名组件

输入密钥文件名作为示例插件(这可以是您想要的任何其他名称)。取消选中“使用密码保护我的密钥文件”选项,然后单击“确定”。单击“保存”。

Mscrm 插件签名组件添加密钥

最后,构建解决方案。右键单击→构建。构建解决方案将生成程序集 DLL,我们将在下一章中使用它来注册此插件。

插件中的异常处理

通常,您的插件逻辑需要处理运行时异常。对于同步插件,您可以返回InvalidPluginExecutionException异常,这将向用户显示错误对话框。错误对话框将包含您传递给异常对象的 Message 对象的自定义错误消息。

如果您查看我们的代码,就会发现我们在 catch 块中抛出了 InvalidPluginExecutionException 异常。

throw new InvalidPluginExecutionException(ex.Message); 

结论

插件对于任何自定义 CRM 实施来说绝对至关重要。在本章中,我们重点了解事件框架模型、管道阶段、消息以及编写示例插件。在下一章中,我们将在 CRM 中注册此插件并查看它在端到端场景中的工作情况。