Power Apps 学习笔记 -- Plugin

1. Plugin 简介

  Plugin基础教程 : Plugin基础教程

插件Plugin:
1. 插件Plugin通常用于默认数据处理操作区间,增加数据默认行为的方法。(无重用性)
2. 类似于工作流workflow, 但是工作流workflow具有重用性。
=> workflow的触发需要在powerApps的流程当中设定,Plugin的触发直接在PluginRegistraion当中进行注册,Plugin的操作更简单。
=> workflow在pluginRegistration当中显示(Workflow Activity),Plugin显示(Plugin)

在这里插入图片描述

2. Plugin 配置

 .NET环境:.NET环境

##安装配置
 1. 安装.NET 环境
 2. 安装 PowerPlatform CLI (使用.NET命令行安装)
dotnet tool install --global Microsoft.PowerApps.CLI.Tool
 3. 安装 Plugin Registration Tool
pac tool prt
##使用Plugin
1. 创建 Class Library(.NET FrameWork)
2. Manuget包:Microsoft.CrmSdk.CoreAssemblies
3. 代码编写
4. 进入属性当中进行密钥签名、检查属性为Debug
5. 解决方案生成 --> 生成文件资源管理器 \bin\Debug\BasicPlugin.dll
6. 登录进入Plugin Registration Tool (注意选择对应环境)
7. 注册程序集 Assembly(注意这里必须全选所有插件,否则会导致其他已有插件被撤掉)
8. 注册步骤Step(核心:定义插件的触发条件、)
9. 运行
10. 调试(install profiler - start profiling - 执行操作 - 附加进程 - startExecution) 

2.1 步骤Step核心分析

  事件执行管道模型(Plugin插件遵循其规律)
在这里插入图片描述

  PreCalidation: 数据库事务管理前,可加入用户过滤等相关取消逻辑的操作。可用于用户安全验证、权限检查等.
  PreOperation: 核心操作前,可调整传入核心操作消息实体的值。可用于核心操作实体值修改等
  MainEvent: 该阶段是执行关键操作(增删改等)的阶段,不允许注册插件.
  PostOperation: 核心操作后,可以获取消息最初传入、操作结束后消息返回的值。尽可能不要修改实体值,避免触发其他事件。
可执行事务管理外的异步操作。可用于创建、修改、更新实体等操作。

  Step注册参数含义
在这里插入图片描述
  a. 正常插件使用了Filtering Attributes时,是只会在指定字段更新时插件才会生效,但是若开启了插件录像 Start Profiling 的时候这个字段过滤会失效,会变为更新操作即生效。

2.2 Plugin 使用注意

  1. 插件程序集会引用当前环境内最新的一个插件程序集
  2. 导入包含插件程序集的解决方案会直引用该解决方案内的插件程序集 ⇒ 不需要发布自定义项就直接生效
  3. PluginRegistration更新会更新所有解决方案内的插件程序集 ⇒ 处理对象是当前环境内所有注册的程序
1. PluginRegistration注册在当前环境没有该插件程序集的时候会注册到默认解决方案最大的空间当中, 如果后期通过解决方案包导入了新的
插件程序集,之前公共最大空间的插件程序集将会被舍弃,系统默认解决方案将会唯一绑定这个新加入的解决方案包当中的插件程序集(此时若注
册了步骤是无法删除的,因为系统当中只有这一个插件程序集)
2. 系统当中如果包含多个解决方案(含共同程序集),将会引用最新的一个,如果有多个删除一个解决方案是可以的,但是如果是最后一个将会唯
一引用,无法删除。
3. 不能删除默认解决方案,删除默认解决方案等效于删除整个环境,整个环境内所有的解决方案当中该插件程序都会被删除

2.3 插件快照

插件快照是一种可以用于获取插件核心操作前后字段值的操作,当用户使用更新操作后想要获取其更新前后数据的数据比较的话就可以通过快照完成 (建议选择需要的快照字段,提高执行效率)
  插件快照只在 Message为 Create(无 Pre Image)、Delete(无 Post Image)、Update、Assign等操作时才会支持.
在这里插入图片描述

namespace BasciPlugin {
    public class SampleAction : IPlugin {
        public void Execute(IServiceProvider serviceProvider) {
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            if(context.MessageName.ToLower() == "update") {
                var target = (Entity)context.InputParameters["Target"];
                var preImange = context.PreEntityImages["Image"];
                var postImange = context.PostEntityImages["Image"];

                Entity order = new Entity("crda9_order"); // 新建一个订单
                order["crda9_reason"] = DateTime.Now + "\n because of ... " + target.Id;
                service.Create(order);
            }
        }
    }
}

  target:只会获取当前用户修改的字段和主键以及一些修改相关的字段信息.
  preImage、postImage:会获取用户快照指定的一些核心操作前后的字段信息

在这里插入图片描述
在这里插入图片描述

3. Plugin 代码

 IPluginExecutionContext接口:IPluginExecutionContext接口

  IPulginExecutionConext: 提供了有关 plugin 执行上下文的信息,包括当前操作的实体记录、操作的类型、执行 plugin 的用户等,
可以使用相关属性和方法进行访问.
using System;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;

namespace BasciPlugin {
    public class FollowupPlugin : IPlugin {
        public void Execute(IServiceProvider serviceProvider) {
            // 跟踪日志
            ITracingService tracingService =(ITracingService)serviceProvider.GetService(typeof(ITracingService));
            // Plugin上下文信息
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            // InputParameters包含请求的实体集(可以是EntityCollection)
            if(context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity) {

                // 组织服务工厂及相关 
                IOrganizationServiceFactory serviceFactory =(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
                try {
                    // context.OutputParameters 核心操作后的响应消息参数
                    // 具体的Plugin相关操作
                    tracingService.Trace("FollowupPlugin: Creating the task activity.");
                }

                catch(FaultException<OrganizationServiceFault> ex) {
                    throw new InvalidPluginExecutionException("An error occurred in FollowUpPlugin.", ex);
                }

                catch(Exception ex) {
                    tracingService.Trace("FollowUpPlugin: {0}", ex.ToString());
                    throw;
                }
            }
        }
    }
}

4. Plugin 使用细节

4.1 Synchronous同步插件应尽量避免做出修改操作

	若在插件A的事务执行阶段当中触发了 插件B的事务,则事务A必须要等待完整插件事务B执行完成后才会有结果,Synchronous
同步插件的Post Operation触发其他事务都会一起纳入完整事务管理

在这里插入图片描述
在这里插入图片描述

  当触发插件A正常执行结果
在这里插入图片描述
  修改代码,在插件B沉睡过后抛出异常,测试插件A的事务是否回滚 – 两个插件会全部回滚
在这里插入图片描述
  补充:

同步插件:尽量避免插件去重复触发自身和其他同步插件或事件
- 重复触发同步插件未设置好结束条件会死循环(系统提示死循环)
- 重复触发同步插件即使设置好结束条件能运行成功,但多个同步插件同时触发也可能因为触发速度过快后台的插件执行可能同时并发(可能导致其他异常)

  结论:PostOperation修改操作尽量使用异步(避免影响本次已有操作)
在这里插入图片描述

4.2 插件间调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

psudd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值