.Net应用程序的执行环境(CLR关于Assembly的搜索算法)

    最近在回顾.Net应用程序的执行环境,这里做一个很小的总结,方面以后需要的时候进行查找:

CLR必须可以找到正确的Assembly,Net提供了Assembly搜索算法,可以根据.config文件(类似于.ini)自定义assembly搜索。

算法分析过程如下:

1、 GAC(Global Assembly Cache)中搜索相应版本的DLL.

2、 配置文件(web.configapp.config)应用程序(.exe)当前目录下

< codebase  version =”Assembly Version"  href =”URL  of assembly”  />

3、 

4、 配置文件(web.configapp.config)

< probing  privatePath =”Paths”  />

 OK,CLR就是根据上面的顺序从14进行搜索Assembly的。如果没有搜索到指定版本的DLL,则程序会抛出异常,提示:DLL文件无法找到。

下面通过程序DEMO来演示这个搜索算法:  二、CodeBase元素

我们新建立一个ClassLibary,名称为:NetLibraryTest,并且在一个类Charles.cs中建立一个方法GetVersion(),为了测试CLR 查找DLL的顺序,我们针对上面的4个顺序实现4个不同的NetLibraryTest.dll 即:

一、GAC(Global Assembly Cache)

public   class  Charles2008
    {
        
public   string  GetVersion()
        {
            
return   " GAC " ;
        }
}

 

 

public   class  Charles2008
    {
        
public   string  GetVersion()
        {
            
return   " CodeBase " ;
        }
}

 

 

 

三、应用程序根目录:

 

public   class  Charles2008
    {
        
public   string  GetVersion()
        {
            
return   " CurrentRoot " ;
        }
}

 

四、Privatepath路径

public   class  Charles2008
  {
        
public   string  GetVersion()
        {
            
return   " Privatepath " ;
        }
   }

 

 

编译上面的4中不同的方法,即得到4个不同的NetLibraryTest.dll文件,另外为了放到GAC中,需要为该dll生成publicKeyToken的值。

 

OK, 下面我另外建立一个项目 :Console 应用程序 NetVersionTest.exe ( 代码很简单 )
代码
  class  Program
    {
        
static   void  Main( string [] args)
        {
            Console.WriteLine(
" Begin Process " );
            
try
            {
                NetLibraryTest.Charles2008 Charles 
=   new  NetLibraryTest.Charles2008();
                Console.WriteLine(Charles.GetVersion());
            }
            
catch  (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.WriteLine(
" End Process " );
            Console.ReadLine();
        }
}

 

配置文件NetVersionTest.exe.config的内容如下:

代码
<? xml version="1.0" encoding="utf-8"  ?>
< configuration >
  
< runtime >
    
< assemblyBinding  xmlns ="urn:schemas-microsoft-com:asm.v1" >
      
< dependentAssembly >
        
< probing  privatePath ="PrivatePath" />
        
< assemblyIdentity  name ="NetLibraryTest"
                              publicKeyToken
="a5015e7d589eac1d"
                              culture
="neutral"   />
        
< codeBase  version ="1.0.242.0"  href ="CodeBase/NetLibraryTest.dll"   />
      
</ dependentAssembly >
    
</ assemblyBinding >
  
</ runtime >
</ configuration >

 

 

 

好了,代码部分就完成了,最后我们生成一个exe文件NetVersionTest.Exe,另外也去掉一些额外的文件,我们这样定义如下的结构:

 

备注:CodeBase文件夹下存放对应的NetLibaryTest.dll文件。即返回值为”CodeBase”

同理:PrivatePath文件夹下也存放的是对应的NetLibaryTest.dll文件,即返回值:”PrivatePath”

GAC文件夹也存放对应的NetLibaryTest.dll文件,即返回值:”GAC”

OK,下面讨论几种情况:

1.    如果GAC里面的NetLibaryTest.dll文件放到GAC中去了,则最后NetVersionTest.exe首先会从GAC中里面去寻找,即最后输出:”GAC”

2.    如果NetLibaryTest.dll没有GAC中注册,则根据前面的顺序,NetVersionTest.exe则会调用CodeBase文件夹下的DLL.即最后输出:”CodeBase”

3.    如果在NetVersionTest.exe.config文件中没有CodeBase元素的配置的话,根据顺序则会调用到应用程序根目录下的NetLibaryTest.dll,即最后输出:”CurrentRoot”.

4.    最后一种情况:没有在GAC中注册,没有配置CodeBase,而且应用程序目录下也没有NetLibaryTest.dll文件,则CLR会从ProbingPrivatePath路径下去寻找指定的dll

5.    如果在1.2.3.4情况下都没有找到的话,则会发生异常,提示不能加载指定版本的dll文件。

 

 说明一下:上面我测试用的Demo的那NetLibaryTest.dll是强名称的程序集,如果是弱名称的程序集则不会再GAC中去寻找(也就是跳过了第一步)。

为了更好的说明CLR搜索程序集的顺序,下面用一个流程图来表示:

 

附:

(1) 初始化绑定。基本上,这意味着从元数据中取出相关的AssemblyRef记录,并查看其中包括什么内容--它的外部程序集名称,它是否经过强命名,是否指定了文化等。

(2) 应用版本策略。这是一些由应用程序、被引用的共享程序集发布者或管理员生成的语句。这些语句包含在XML配置文件中,并且只是将程序集的特定版本(或一组版本)重定向到不同的版本。

 

OK,本文讨论就到这里了。很简单,就是CLR搜索Assembly的算法。这里通过一个Demo来对这种搜索的算法进行了验证和测试。

欢迎朋友们给予宝贵的意见。谢谢!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值