AppDomain.CurrentDomain.AssemblyResolve in dynamics crm

因此,我参考了许多引用AppDomain.CurrentDomain.AssemblyResolve文章,以便在运行时将嵌入式资源中的DLL加载到插件中(不使用IlMerge)。 但是,当我插入此代码时,事件处理程序永远不会在插件为我的主库抛出TypeLoadException消息之前接收该线程。

我已经尝试将代码放在静态构造函数中,在Execute方法内部和主构造函数中; 虽然事件处理程序已注册,但处理程序中的断点不会被命中。

环境是Dynamics CRM 2011,最新汇总并使用SDK开发人员工具插件项目和插件类生成。

任何人都知道我需要做些什么才能让它发挥作用?

在您通过该回调加载计划的程序集中引用任何类型之前,发生AssemblyResolve事件注册非常重要。 即使您没有在静态构造函数中引用类型,也必须确保类中没有静态变量, 或者它是引用外部程序集中类型的基类

这是我如何做到的:我有一个单独的类来处理程序集加载,恰当地命名为AssemblyLoader:

 using System; using System.IO; using System.Linq; using System.Reflection; internal static class AssemblyLoader { internal static void RegisterAssemblyLoader() { AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.AssemblyResolve -= OnResolveAssembly; currentDomain.AssemblyResolve += OnResolveAssembly; } private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args) { return LoadAssemblyFromManifest(args.Name); } private static Assembly LoadAssemblyFromManifest(string targetAssemblyName) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); AssemblyName assemblyName = new AssemblyName(targetAssemblyName); string resourceName = DetermineEmbeddedResourceName(assemblyName, executingAssembly); using (Stream stream = executingAssembly.GetManifestResourceStream(resourceName)) { if (stream == null) return null; byte[] assemblyRawBytes = new byte[stream.Length]; stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length); return Assembly.Load(assemblyRawBytes); } } private static string DetermineEmbeddedResourceName(AssemblyName assemblyName, Assembly executingAssembly) { //This assumes you have the assemblies in a folder named "EmbeddedAssemblies" string resourceName = string.Format("{0}.EmbeddedAssemblies.{1}.dll", executingAssembly.GetName().Name, assemblyName.Name); //This logic finds the assembly manifest name even if it's not an case match for the requested assembly var matchingResource = executingAssembly.GetManifestResourceNames() .FirstOrDefault(res => res.ToLower() == resourceName.ToLower()); if (matchingResource != null) { resourceName = matchingResource; } return resourceName; } } 

然后,在我的插件类中,我使用静态构造函数来调用我的AssemblyLoader。 通过将逻辑移动到单独的类中,我限制了我在插件类的静态上下文中引用的类型的数量,从而降低了我不小心引用外部程序集中的内容的风险。

 using System; using Microsoft.Xrm.Sdk; public class MyPlugin : IPlugin { static MyPlugin() { AssemblyLoader.RegisterAssemblyLoader(); } public void Execute(IServiceProvider serviceProvider) { //... } } 

我还将外部程序集的所有用法移动到其他类中,以便我的插件类根本不使用它。 大多数情况下,这是非常谨慎的。