Mik*_*_II 5 c# plugins dynamics-crm-2011
因此,我在很多文章中引用了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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,在我的插件类中,我使用静态构造函数调用我的AssemblyLoader.通过将逻辑移动到单独的类中,我限制了我在插件类的静态上下文中引用的类型的数量,从而降低了我不小心引用外部程序集中的内容的风险.
using System;
using Microsoft.Xrm.Sdk;
public class MyPlugin : IPlugin
{
static MyPlugin()
{
AssemblyLoader.RegisterAssemblyLoader();
}
public void Execute(IServiceProvider serviceProvider)
{
//...
}
}
Run Code Online (Sandbox Code Playgroud)
我还将外部程序集的所有用法移动到其他类中,以便我的插件类根本不使用它.大多数情况下,这是非常谨慎的.
| 归档时间: |
|
| 查看次数: |
3653 次 |
| 最近记录: |