动态CRM自定义工作流活动和GAC参考版本

本文关键字:GAC 参考 版本 活动 CRM 自定义 工作流 动态 | 更新日期: 2023-09-27 18:03:38

我在CRM工作流程中遇到了一个错误,该工作流运行自定义活动,这些活动引用了GAC的通用程序集,但不同版本。情况如下:

程序集A和程序集B(都是自定义活动)引用程序集C,其中包含A和B的基类(继承自CodeActivity)以及crmsvcutil生成的类。汇编C在GAC中存在多个版本。现在,我在CRM中创建了一个新的属性,用crmsvcutil重新生成了早期的类型,将汇编C的版本更新为1.0.0.3并放入GAC中,重建汇编B(使用新属性)并使用插件注册工具更新。

此错误出现在同时引用程序集A和B的工作流中,并显示一条错误消息"assembly。"类型"不能转换为"程序集。Type"。在基类(汇编C)中,我们设置了一个汇编属性,使其能够处理强类型:

IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
var type = Type.GetType("Microsoft.Crm.Workflow.SynchronousRuntime.WorkflowContext, Microsoft.Crm.Workflow, Version=5.0.0.0");
type.GetProperty("ProxyTypesAssembly").SetValue(serviceFactory, typeof(XrmServiceContext).Assembly, null);
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

在我看来,CRM将基类与代理类型一起缓存,并尝试在汇编B上使用它,尽管它引用了新版本的c。如果我创建一个仅包含汇编B活动的工作流,它工作得很好,只有当汇编a在相同的WF和B之前被引用时。

这是一个问题,现在在生产环境,我正试图找到一个修复它。我知道我可以更新汇编A以使用新版本的C,并且我在测试环境中做到了这一点,但由于汇编比两个多很多,因此必须执行许多测试。

  1. 我可以以某种方式指向更新的汇编B到旧版本的C(并使用索引器与属性名称的新属性)?我尝试将C的汇编版本恢复到1.0.0.2,再次编译B,但随后我得到一个错误,即不能在插件注册工具中更新汇编。
  2. 有人能解释一下程序集如何以及在哪里保持引用程序集的版本吗?这在。net中一般是如何工作的?

最奇怪的是,我试图将基类和早期类型类复制到汇编B中(在它自己的命名空间中),完全删除对汇编C的引用,在插件注册表工具中更新,我得到了完全相同的错误,这次是"AssemblyC"。不能转换为"AssemblyB.type"。我不明白为什么我完全删除了对汇编c的引用。

任何建议都是感激的,提前感谢。

编辑:我刚刚发现这只与对话有关。它在工作流中工作得很好。想起什么了吗?

动态CRM自定义工作流活动和GAC参考版本

几个想法

对我来说,看起来早期绑定程序集有时会产生更多的问题,而不是帮助解决问题。这里的主要问题是缺乏透明度。一切都在幕后隐式地完成。用户对此没有任何控制。

我注意到CRM在一个AppDomain中自动解析早期绑定的程序集。这基本上意味着,如果你有两个程序集使用不同版本的同一早绑定程序集,首先加载的程序集将把它的早绑定程序集拖到AppDomain和所有其他插件中,CWA将被迫使用先前加载的早绑定程序集。

如何修复?如果这些自定义工作流活动在不同的工作流中使用-请尝试单独注册程序集。我还没有尝试过那个场景,但是如果这些工作流不共享相同的AppDomain早期绑定类型,将不会混乱。

另一种方法:尝试将所有早期绑定的程序集与CWA捆绑在一起。可能会导致异常大的文件,但很可能会解决您的问题(您也可以从早期绑定程序集中删除未使用的定义,使其更精简)。

还有一个想法:查看这个链接。在XrmToolBox这里,我们正试图找到解决这个问题的方法。基本上,有一种方法可以手动将后绑定程序集强制转换为选定的早绑定程序集。

XrmToolBox也包含这个建议,允许直接指定使用哪个程序集