我正在尝试使用AppDomain.AssemblyResolve
事件处理异常,同时解析在运行时加载的某些dll的程序集(SerializationException for dynamically loaded 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
不太有用。
你能建议我一些解决方法吗?
有没有办法在事件被触发时传递一些其他参数?
答案 0 :(得分:15)
您可以从目录中定义程序集的字典,如下所示:
private readonly IDictionary<string,Assembly> additional =
new Dictionary<string,Assembly>();
使用已知目录中的程序集加载此字典,如下所示:
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;
这应该可以解决问题。
答案 1 :(得分:0)
如果您知道可能包含要计划反序列化的类型的程序集列表,那么在执行序列化之前简单地预加载所有程序集可能会更好。
当触发AssemblyResolve事件时,您没有关于导致加载的类型的信息,而只是关于程序集名称的信息。目前还不清楚为什么你会在这种情况下通过某种特定类型查找装配。
请注意,如果2个程序集碰巧具有相同的标识(即非强签名的情况下的文件名),并且已经加载了一个事件,则即使在已加载的程序集中找不到类型,也不会触发事件。< / p>
出于历史目的链接到该文章:Resolving Assembly Loads。