使用AppDomain.AssemblyResolve事件

我正在尝试使用AppDomain.AssemblyResolve事件来处理exception,同时解析在运行时加载的某些dll的程序集( SerializedException用于动态加载的Type )。

当事件被触发时,我在我的目录中加载所有DLL并创建一个Assembly数组,然后我使用这个方法来获得包含我指定的类型的Assembly

 public static Assembly GetAssemblyContainingType(String completeTypeName, Assembly[] assemblies) { Assembly assembly = null; foreach (Assembly currentassembly in assemblies) { Type t = currentassembly.GetType(completeTypeName, false, true); if (t != null) { assembly = currentassembly; break; } } return assembly; } 

问题是此代码仅适用于AssemblyQualifiedName ,并且事件提供的ResolveEventArgs.Name不太有用。

你能建议我一些解决方法吗?

有没有办法在事件被触发时传递一些其他参数?

您可以从目录中定义程序集的字典,如下所示:

 private readonly IDictionary additional = new Dictionary(); 

使用已知目录中的程序集加载此字典,如下所示:

 foreach ( var assemblyName ... corresponding to DLL names in your directory... ) { var assembly = Assembly.Load(assemblyName); additional.Add(assembly.FullName, assembly); } 

提供钩子的实现……

 private Assembly ResolveAssembly(Object sender, ResolveEventArgs e) { Assembly res; additional.TryGetValue(e.Name, out res); return res; } 

…并将其连接到事件:

 AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += ResolveAssembly; AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; 

这应该可以解决问题。

如果您知道可能包含要计划反序列化的类型的程序集列表,那么在执行序列化之前简单地预加载所有程序集可能会更好。

当AssemblyResolve事件被触发时,您没有关于导致加载的类型的信息,而只有组件名称的信息。 目前还不清楚为什么你会在这种情况下通过某种特定类型查找assembly。

请注意,如果2个程序集碰巧具有相同的标识(即非强签名的情况下的文件名),并且已经加载了一个事件,则即使在已加载的程序集中找不到类型,也不会触发事件。

出于历史目的链接到该文章: 解决assembly载荷 。