编写自定义 Azure 兼容插件

编写适用于Azure的插件类似于编写任何其他 Dataverse 插件。 但是,除了调用任何所需的 Web 服务方法之外,插件还必须包含代码,以启动将当前事务的执行上下文发布到Azure 服务总线。

插件设计注意事项

对于同步执行的插件,建议的设计是让插件向Azure发送消息,以便从侦听器应用程序或其他外部服务检索信息。 在Azure 服务总线终结点上使用双向或 REST 协定允许将数据字符串返回到插件。

不建议同步插件使用Azure 服务总线通过外部服务更新数据。 如果外部服务不可用或需要更新的数据量很大,则可能会出现问题。 同步插件应快速执行,不应在执行耗时操作时阻塞组织中所有已登录的用户。 此外,如果调用了该插件的当前核心操作发生回滚,则插件所做的任何数据更改都将被撤销。 此回滚可能会使 Dataverse 和外部服务处于非同步状态。

同步注册插件可以将当前事务的执行上下文发布到Azure 服务总线。

编写插件代码

在下面的示例插件中,已添加代码以获取Azure服务提供程序,并通过调用 Execute(EntityReference, IExecutionContext) 启动将执行上下文发布到服务总线。 添加了跟踪代码以方便调试插件,因为插件必须在沙盒中运行。

Note

此代码中传递给构造函数的 serviceEndpointId 即您在《操作指南:配置 Azure (SAS) 以与 Dataverse 集成》中所述创建服务端点时获得的密钥

可以使用使用浏览器向 Web API 请求来查询环境的 GET 可用服务终结点,查询如下所示: [organization Uri]/api/data/v9.0/serviceendpoints?$select=name,description,serviceendpointid

using System;
using System.Diagnostics;
using System.Threading;
using System.Runtime.Serialization;

using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;

using Microsoft.Xrm.Sdk;

namespace Microsoft.Crm.Sdk.Samples
{
    /// <summary>
    /// A custom plug-in that can post the execution context of the current message to the Windows
    /// Azure Service Bus. The plug-in also demonstrates tracing which assist with
    /// debugging for plug-ins that are registered in the sandbox.
    /// </summary>
    /// <remarks>This sample requires that a service endpoint be created first, and its ID passed
    /// to the plug-in constructor through the unsecure configuration parameter when the plug-in
    /// step is registered.</remarks>
    public sealed class SandboxPlugin : IPlugin
    {
        private Guid serviceEndpointId; 

        /// <summary>
        /// Constructor.
        /// </summary>
        public SandboxPlugin(string config)
        {
            if (String.IsNullOrEmpty(config) || !Guid.TryParse(config, out serviceEndpointId))
            {
                throw new InvalidPluginExecutionException("Service endpoint ID should be passed as config.");
            }
        }

        public void Execute(IServiceProvider serviceProvider)
        {
            // Retrieve the execution context.
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            // Extract the tracing service.
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            if (tracingService == null)
                throw new InvalidPluginExecutionException("Failed to retrieve the tracing service.");

            IServiceEndpointNotificationService cloudService = (IServiceEndpointNotificationService)serviceProvider.GetService(typeof(IServiceEndpointNotificationService));
            if (cloudService == null)
                throw new InvalidPluginExecutionException("Failed to retrieve the service bus service.");

            try
            {
                tracingService.Trace("Posting the execution context.");
                string response = cloudService.Execute(new EntityReference("serviceendpoint", serviceEndpointId), context);
                if (!String.IsNullOrEmpty(response))
                {
                    tracingService.Trace("Response = {0}", response);
                }
                tracingService.Trace("Done.");
            }
            catch (Exception e)
            {
                tracingService.Trace("Exception: {0}", e.ToString());
                throw;
            }
        }
    }
}

在插件代码中,可以在启动发布之前更新上下文中的可写数据。 例如,可以将键/值对添加到上下文中的共享变量。

插件注册

注册支持 Azure 的自定义插件时,有一些限制。 必须注册插件才能在沙盒中执行。 沙盒注册将插件限制为调用 IOrganizationService 方法、Azure解决方案方法或使用 Web 客户端访问网络。

对于注册为在异步模式下执行的插件,与其他异步插件相比,插件执行的顺序是不能保证的。 此外,异步插件始终在 Dataverse 核心操作后执行。

处理 服务总线 发布失败

服务总线 发布失败时的预期行为取决于插件是注册为同步执行还是异步执行。 对于异步插件,实际将执行上下文发布到 Service Bus 的系统作业将重试该发布操作。 对于同步已注册的插件,会返回异常。 更多信息运行时错误的管理与通知

Important

仅对于以异步方式注册的插件,当向 Azure 服务总线 发布数据后发生发布失败,且异步作业重试时,整个插件逻辑将重新执行。 因此,除了修改上下文并将消息发布到 服务总线 之外,不要向自定义的 Azure 感知插件添加任何其他逻辑。

对于注册为异步执行的插件,通过服务总线发送的消息正文中包含的 RemoteExecutionContext 包括 OperationId 属性和 OperationCreatedOn 属性。 这些属性包含与相关系统作业(AsyncOperation)记录中的 AsyncOperationIdCreatedOn 列相同的数据。 如果必须重试向 Azure 服务总线 发送消息,这些附加属性有助于排序和重复检测。

另见

Azure 集成
在Azure解决方案中使用Microsoft Dataverse数据
示例:Azure 感知自定义插件
编写插件
事件执行管道
注册和部署插件