zoukankan      html  css  js  c++  java
  • 动态决定加载dll多个版本的完美方案

    最近同事遇到一个问题,关于程序需要在动态的时候决定究竟要加载dll的哪个版本.

    我们程序现在依赖于cad的一个simple.dll. cad有2004,有2006.这个simple.dll是强命名的,04跟06虽不同但版本号是一样的,不可以放在同一目录下.我们现在的程序需要同时支持cad 2004,2006.当客户端安装的是Cad2004时我们要用04的simple.dll功能,安装的是cad2006时,使用06的simple.dll.

    我们知道.net提供了一种机制可以保证使用最新版本的dll或者由用户决定想用哪个版本.具体可见 How the Runtime Locates Assemblies.但是这种方案主要用于解决多个版本的问题,明显跟我们遇到的情况有点不同.而且此种方法是由config文件决定的,实际上也是达不到运行时决定加载哪个版本,只能事先配置config文件.

    那么想到的另一种方法就是动态加载.然而动态加载在编译期丧失了类型透明的好处,只能通过Invoke去调用方法.现在需要大量调用simple.dll里的方法,需要额外做的事情就太多了.

    今天在看 蝈蝈俊的:使用VS2005的 ClickOnce 技术实现按需下载组件得到启示,并且尝试后证明是可行了.

    首先我们照样直接add reference "simple.dll",该干嘛就干嘛.
    然后我们制造事故,在程序的目录下不放置simple.dll(设置Copy Local 属性false即可),让CLR加载程序集失败,并触发AssemblyResolve 事件,然后我们在此事件里动态加载simple.dll.

    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

     Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
     
    {
         Assembly newAssembly 
    = null
         
    // Get the DLL name from the Name argument.
         string[] nameParts = args.Name.Split(',');
         
    string dllName = nameParts[0];
         
    try
         
    {
             
    string path = "";
             
    if (condition)
             
    {
                 path 
    = "";
             }

             newAssembly 
    = Assembly.LoadFile(path);
         }

         
    catch (Exception e)
         
    {
             
    throw (e);
         }


         
    return newAssembly;
     }

    用几行代码就可以完美解决了此问题.(PS.我喜欢完美哈,用在这里应该也很恰当:-) 心情愉快地说)

  • 相关阅读:
    oracle 动态SQL
    Oracle 学习PL/SQL
    SQL优化原理
    JAVA环境配置
    Java接口
    Java数据类型、操作符、表达式
    C#-VS配置开发环境-摘
    Java版本
    网站构建
    Java 时间、字符串
  • 原文地址:https://www.cnblogs.com/anders06/p/800472.html
Copyright © 2011-2022 走看看