与AppDomain.AssemblyResolve事件工作事件、工作、AppDomain、AssemblyResolve

2023-09-03 00:38:38 作者:活在人间

我试图使用 AppDomain.AssemblyResolve 事件来处理异常,而解决某些DLL在运行时加载(的 SerializationException动态加载的类)。

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在我的目录下,并创建一个组装数组,然后我用这个方法来获取大会包含我指定类型:

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

现在的问题是,这个code只适用于一个 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);
}

提供一个实现了钩......

Provide an implementation for the hook...

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;

这应该可以解决问题。