在項目的配置文件Web.config中,會看到<runtime>節點,以及包含在其中的<assemblyBinding>節點,這顯然與程序集有關,這些節點到底何時被用到呢?
在默認情況下,在運行時,JIT編譯器將IL代碼編譯成本地代碼時,會查看IL代碼中的字段、局部變量、方法參數等引用了哪些類型,然後借助程序集的TypeRef和AssemblyRef元數據,內部使用System.Reflection.Assembly的Load方法來確定需要被加載的程序集,包括module。
Load方法接收一個代表強類型名稱程序集的字符串,類似如下:
Assembly a = Assembly.Load("somename, Version=1.2.3.4" +"Culture=neutral, PublicKeyToken=........");a.CreateInstance("someclassname");
在Load方法內部,會使用一個叫做"程序集解析(assembly resolver)"的機制尋找程序集。首先會遵循"版本策略"去尋找程序集合適的版本。這個"版本策略"可以在配置文件中配置。在"C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machine.config"中完成計算機級別的配置,在當前項目的Web.config中完成應用程序級別的配置。例如在Web.config中:
<runtime><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" /><bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" /></dependentAssembly><dependentAssembly><assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /><bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" /></dependentAssembly><dependentAssembly><assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" /><bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" /></dependentAssembly><dependentAssembly><assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" /><bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" /></dependentAssembly><dependentAssembly><assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" /><bindingRedirect oldVersion="1.0.0.0-1.3.0.0" newVersion="1.3.0.0" /></dependentAssembly></assemblyBinding></runtime>
如果想取消"版本策略",可以在Web.config中按如下配置:
<runtime><rt:assemblyBinding><rt:publisherPolicy apply="no" /></rt:assemblyBinding></runtime>
以上,程序集是按需加載的,當程序運行,需要用到某個類型,就加載該類型所在的程序集,把該類型加載到內存中。
如果不想讓程序集按需加載,要麼把類型設置為靜態的,要麼直接告訴CLR如何加載程序集。使用System.Reflection.Assembly的靜態方法LoadFrom就可以加載固定位置的某個程序集。
舉例:創建一個名稱為Customer的類庫,並創建CustomerBehavior類
using System;namespace Customer{public class CustomerBehavior{public void SayHello(){Console.WriteLine("hello");}}}
把Customer類庫的生成路徑設置為F盤的temp文件夾。在客戶端通過LoadFrom動態加載F盤temp文件夾下的Customer.dll程序集。
static void Main(string[] args){Assembly a = Assembly.LoadFrom("f:\\temp\\Customer.dll");var type = a.GetType("Customer.CustomerBehavior");Console.WriteLine(type.Assembly.FullName);Console.ReadKey();}
總結:在CLR內部使用System.Reflection.Assembly的Load方法加載程序集,而加載的程序集版本策略可以通過配置文件設置。