加载多个版本的DLL

Mar*_*ark 5 c# dll

我有一个C#应用程序,它与一些硬件(USB设备)连接,如下所示: C# application -> intermediate DLL -> hardware DLL -> hardware.中间DLL和硬件DLL随USB设备一起提供,因此我无法控制它们.

中间DLL是唯一我需要它这在VS的项目包括,因为这就是我所说的.然后硬件DLL位于同一目录中,因此必须自动找到.

现在,使用不同的硬件DLL发布了新版本的硬件设备.旧DLL与新硬件不兼容,新DLL与旧硬件不兼容.

如何使我的应用程序与两个硬件一起工作?我想我需要根据需要加载和卸载每个DLL?

pli*_*nth 4

这是我针对类似问题所做的操作。我有一段代码想要使用,但我必须在运行时加载 dll。所以我在我的项目中引用它,但我没有将它放在与其余程序集相同的目录中。相反,在使用代码中,我有一些如下所示的代码:

// constructor called from a static constructor elsewhere
MyDllLoader(string hardwareFolder) {
    _hardwareFolder = hardwareFolder;
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
    SeeIfAlreadyLoaded();
}


private void SeeIfAlreadyLoaded() {
    // if the assembly is still in the current app domain then the AssemblyResolve event will
    // never fire.
    // Since we need to know where the assembly is, we have to look for it
    // here.
    Assembly[] assems = AppDomain.CurrentDomain.GetAssemblies();
    foreach (Assembly am in assems)
    {
        // if it matches, just mark the local _loaded as true and get as much
        // other information as you need
    }
}

System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
    string name = args.Name;
    if (name.StartsWith("Intermediate.dll,"))
    {
        string candidatePath = Path.Combine(_hardwareFolder, "Intermediate.dll");
        try {
            Assembly assem = Assembly.LoadFrom(candidatePath);
            if (assem != null) {
                _location = candidateFolder;
                _fullPath = candidatePath;
                _loaded = true;
                return assem;
            }
        }
        catch (Exception err) {
            sb.Append(err.Message);
        }
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

还有另一种解决方案 - 它很复杂,但我已经完成并为您完成了工作。您声明一个抽象类,例如 MyHardwareAbstraction,它具有您想要的方法的签名,并针对该接口进行编码。然后,您编写一些代码,给出程序集的路径,加载它并动态定义一个与 MyHardwareAbstraction 匹配的新类,并使其映射到您想要的实际对象的实例。 几年前我写了一篇关于如何做到这一点的博客

这样做的好处是,您在代码中使用抽象类型并对其进行处理,然后适配器编译器将在运行时编译一个新类,该类将使用其他类型作为目标类型来完成该抽象类型。它也相当有效。