我在CRM工作流程中遇到错误,这些错误运行自定义活动,这些活动引用了GAC的常见程序集,但版本不同。情况如下:
程序集A和程序集B(两个自定义活动)引用程序集C,它包含A和B的基类(继承自CodeActivity)以及crmsvcutil生成的类。程序集C在GAC中存在多个版本。现在,我在CRM中创建了一个新属性,使用crmsvcutil重新生成早期类型,将程序集C的版本更新为1.0.0.3并将其放入GAC,重建程序集B(使用新属性)并使用插件注册工具更新它。
错误显示在工作流中,它引用程序集A和B,并显示错误消息“assembly.type”无法转换为“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的活动的工作流程,它可以正常工作,只有在相同的WF和B之前引用程序集A.
这是生产环境中的一个问题,我正在尝试找到它的修复程序。我知道我可以更新程序集A以使用新版本的C并且我在测试环境中完成了它,但由于有更多的程序集,所以必须执行两次,许多测试。
最奇怪的是,我试图将基类和早期类型类复制到程序集B(在它自己的命名空间中),完全删除对程序集C的引用,在插件注册表工具中更新,我得到了完全相同的错误,这次“AssemblyC.type”无法转换为“AssemblyB.type”。我不明白当我完全删除对程序集C的引用时。
任何建议都表示赞赏,提前谢谢。
编辑:我刚刚发现这只涉及对话框。它适用于工作流程。那铃响了吗?答案 0 :(得分:0)
几个想法。
对我来说,看起来早期的装配有时会产生更多问题,而不是解决问题。这里的主要问题是缺乏透明度。一切都是在幕后隐蔽地完成的。用户对此无法控制。
我注意到CRM会在一个AppDomain
内自动解析早期绑定的程序集。这基本上意味着,如果你有两个使用相同早期绑定程序集的不同版本的程序集,那么首先加载的程序集会将其早期绑定程序集拖动到AppDomain
以及所有其他插件CWA
s将被迫使用先前加载的早期装配。
如何解决?如果在不同的工作流程中使用这些自定义工作流活动 - 请尝试单独注册程序集。我还没有尝试过这种情况,但是如果这些工作流程不会共享相同的AppDomain
早期绑定类型,那么就不会搞砸了。
另一种方法:尝试将所有早期绑定程序集与CWA
捆绑在一起。可能会导致异常庞大的文件,但很可能会解决您的问题(并且您还可以从早期绑定程序集中删除未使用的定义以使其变得更加苗条)。
还有一个想法:检查一下link。在XrmToolBox
中,我们正在尝试为该问题找到解决方案。基本上,有一种方法可以将后期绑定的程序集手动转换为选定的早期绑定。
XrmToolBox
还包含此proposal,允许直接指定要使用的程序集。