使用 AppDomain.AssemblyResolve 事件 [英] Working with AppDomain.AssemblyResolve event

查看:42
本文介绍了使用 AppDomain.AssemblyResolve 事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 AppDomain.AssemblyResolve 事件来处理异常,同时解析运行时加载的某些 dll 的程序集 (动态加载类型的序列化异常).

I'm trying to use AppDomain.AssemblyResolve event to handle exceptions while resolving Assemblies of some dll loaded at runtime (SerializationException for dynamically loaded Type).

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

When the event is fired, I load all DLLs in my directory and create an Assembly array, then I use this method to get the Assembly containing the type I specify:

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 用处不大.

The problem is that this code works only with an AssemblyQualifiedName, and the ResolveEventArgs.Name provided by the event is not so useful.

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

Can you suggest me some workaround?

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

Is there a way to pass some other arguments to the event when it is fired?

推荐答案

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

You can define a dictionary of the assemblies from your directory, like this:

private readonly IDictionary<string,Assembly> additional =
    new Dictionary<string,Assembly>();

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

Load this dictionary with the assemblies from your known directory, like this:

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;
}

...并将其与事件挂钩:

...and hook it up to the event:

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

这应该可以解决问题.

这篇关于使用 AppDomain.AssemblyResolve 事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆