加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 加载多个版本的DLL

发布时间:2020-12-15 05:38:35 所属栏目:百科 来源:网络整理
导读:我有一个C#应用程序,它与一些硬件(USB设备)连接如下: C#应用程序 – 中间DLL – 硬件DLL – 硬件.中间DLL和硬件DLL随USB设备一起提供,因此我无法控制它们. 中间DLL是唯一需要包含在VS项目中的DLL,因为这就是我所说的.然后硬件DLL位于同一目录中,因此必须自
我有一个C#应用程序,它与一些硬件(USB设备)连接如下:
C#应用程序 – >中间DLL – >硬件DLL – >硬件.中间DLL和硬件DLL随USB设备一起提供,因此我无法控制它们.

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

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

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

解决方法

这是我为类似问题所做的事情.我有一大堆我想要使用的代码,但我必须在运行时加载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;
}

还有另一个解决方案 – 它很复杂,但我已经完成了它并为你完成了工作.您声明了一个抽象类,比如说MyHardwareAbstraction,它具有您想要的方法的签名,并且您可以针对该接口进行编码.然后编写一些代码,这些代码给出了程序集的路径,加载它并动态定义一个匹配MyHardwareAbstraction的新类,并使其映射到您想要的实际对象的实例上. I wrote a blog several years ago on how to do this.

执行此操作的好处是您在代码中使用抽象类型并对其进行操作,然后适配器编译器将在运行时编译一个新类,该类将使用其他类型作为目标类型来完成该抽象类型.它也很有效率.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读