D365插件本地单元测试遇强名称程序集加载错误求助
Dynamics 365插件单元测试强命名程序集错误解决方法
我想要本地测试Dynamics 365插件,我的解决方案包含多个依赖项目,主插件项目依赖CRM.CLIENTE.Plugin.Repository等项目。
单元测试代码
namespace CRM.CLIENTE.Plugin.Test { [TestClass] public class UnitTest1 { [TestMethod] [Description("Teste Template ")] [Owner("Alexandre")] public void TestMethod1() { Guid id = Guid.NewGuid(); // init XrmFakedContext fakecontext = new XrmFakedContext(); XrmFakedPluginExecutionContext pluginContext = fakecontext.GetDefaultPluginContext(); XrmFakedTracingService iTracing = new XrmFakedTracingService(); //Prepare Entity target = new Entity("Contact") { Id = id }; target.Attributes.Add("telephone1","90381290381 8876"); Entity postimage = new Entity("Contact") { Id = id }; postimage.Attributes.Add("telephone1", "90381290381 88763232"); ParameterCollection inputParameter = new ParameterCollection(); inputParameter.Add("Target", target); EntityImageCollection postImages = new EntityImageCollection(); postImages.Add("PostImage", postimage); pluginContext.InputParameters = inputParameter; pluginContext.PostEntityImages = postImages; fakecontext.Initialize(new List<Entity>() { postimage }); //Execute fakecontext.ExecutePluginWith<PreOperationFormatPhoneCreateUpdate>(pluginContext); //Assert Entity teste = fakecontext.CreateQuery("Contact").FirstOrDefault(); Assert.Equals("903812903818876", teste["telephone1"]); iTracing.Trace("Tested Trace in Account Create"); } } }
主插件类代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Xrm.Sdk; using System.Text.RegularExpressions; using CRM.CLIENTE.Plugin.Comum; using CRM.CLIENTE.Plugin.Repository.Repository; using CRM.CLIENTE.Plugin.Repository.Repository.Interface; namespace CRM.CLIENTE.Plugin.Service { public class PreOperationFormatPhoneCreateUpdate : BasePlugin { protected override void ExecuteCrmPlugin(IPluginExecutionContext context, IOrganizationService service) { IContactRepository _contactRepository = new ContactRepository(); _contactRepository.formatarTelefone(context); } } }
插件基类代码
namespace CRM.CLIENTE.Plugin.Comum { public abstract class BasePlugin : IPlugin { public IPluginExecutionContext localContext { get; set; } public IOrganizationService OrganizationService { get; private set; } public void Execute(IServiceProvider serviceProvider) { if (serviceProvider == null) { throw new InvalidPluginExecutionException("serviceProvider"); } try { localContext = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); if (!localContext.InputParameters.ContainsKey("Target")) throw new InvalidPluginExecutionException("No target found"); IOrganizationService service = ((IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory))).CreateOrganizationService(null); ExecuteCrmPlugin(localContext, service); } catch (InvalidPluginExecutionException e) { throw (e); } } protected virtual void ExecuteCrmPlugin(IPluginExecutionContext localcontext, IOrganizationService service) { // Implementar o código do Plugin no proprio Plugin } } }
Repository项目代码
using CRM.CLIENTE.Plugin.Domain.Domain; using CRM.CLIENTE.Plugin.Factory.Factory; using CRM.CLIENTE.Plugin.Repository.Comum; using CRM.CLIENTE.Plugin.Repository.Repository.Interface; using Microsoft.Xrm.Sdk; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace CRM.CLIENTE.Plugin.Repository.Repository { public class ContactRepository : IContactRepository { public Entity formatarTelefone(IPluginExecutionContext context) { Entity entity2 = context.InputParameters["Target"] as Entity; Contact contato = new ContactFactory().d365ToObject(entity2); contato.TelefoneComercial = Regex.Replace(contato.TelefoneComercial, @"[^\d]", ""); return new ContactFactory().objectToD365(contato); } } }
运行错误信息
System.IO.FileLoadException: 'Could not load file or assembly 'CRM.CLIENTE.Plugin.Repository, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. A strong-named assembly is required. (Exception from HRESULT: 0x80131044)'
问题原因
Dataverse插件部署要求程序集必须是强命名的,而你的测试项目引用的依赖项目(如CRM.CLIENTE.Plugin.Repository)未进行强命名签名,导致测试加载程序集失败。
解决步骤
为所有依赖项目添加强命名密钥
- 右键点击需要签名的项目(如CRM.CLIENTE.Plugin.Repository、CRM.CLIENTE.Plugin.Comum、CRM.CLIENTE.Plugin.Service等),选择「属性」
- 切换到「签名」选项卡,勾选「为程序集签名」
- 在「选择强名称密钥文件」下拉框中选择「新建」,输入密钥文件名,取消勾选「使用密码保护密钥文件」(测试环境可简化操作),点击确定
- 保存项目设置,重新生成所有项目
更新测试项目引用
- 删除测试项目中对未签名程序集的引用
- 重新添加对签名后生成的程序集的引用(路径一般在项目的
bin/Debug或bin/Release目录下)
修复测试与插件逻辑问题(避免后续断言失败)
- 主插件中需将Repository返回的格式化实体写回上下文:
protected override void ExecuteCrmPlugin(IPluginExecutionContext context, IOrganizationService service) { IContactRepository _contactRepository = new ContactRepository(); Entity formattedContact = _contactRepository.formatarTelefone(context); // 将格式化后的实体更新回Target参数 context.InputParameters["Target"] = formattedContact; } - 测试代码中使用
Assert.AreEqual替换Assert.Equals(后者是Object方法,不会触发测试断言):Assert.AreEqual("903812903818876", teste["telephone1"]);
- 主插件中需将Repository返回的格式化实体写回上下文:
重新运行测试
- 清理解决方案,重新生成所有项目后执行单元测试
内容的提问来源于stack exchange,提问作者Bechelli
相关产品推荐
相关产品推荐

