Assembly.Load, Assembly.LoadFrom, Assembly.LoadFile說明
前言
最近使用動態建立物件時,發現如果沒有把該DLL放在Bin目錄就無法順利建立該物件,可是該DLL已有拉進了GAC了呀! 為何要再把DLL放到Bin目錄呢?與同事研究之下才知道,如果用GAC的組件要加入整個組件的資訊。
研究
Assembly.Load(“dll name").CreateInstance(“namespace.class")
Assembly.Load("RM").CreateInstance("RM.Operation.E5003Handler") => 這種方式RM.dll一定要放在bin目錄。
Assembly.Load("RM, Version=1.0.3500.0, Culture=neutral, PublicKeyToken=FE1CD4D284342EE2").CreateInstance("RM.Operation.E5003Handler")=>如果RM.DLL在GAC中,要建立它的實體的話,就要給它的相關資訊哦!
那如果要從特定檔案建立物件呢? 那就要用Assembly.LoadFrom or Assembly.LoadFile。
Assembly.LoadFrom(“c:\RM.dll").CreateInstance("RM.Operation.E5003Handler", true)
Assembly.LoadFile(“c:\RM.dll").CreateInstance("RM.Operation.E5003Handler", true)
看到CodeProject還有看到以下的用法。
Assembly.LoadFrom(“c:\RMAP.EXE").CreateInstance("RMAP.Form1", true)
連網站上的EXE也能建立。
Assembly.LoadFrom(“http://www.myweb.com/test/RMAP.EXE").CreateInstance("RMAP.Form1", true)
那LoadFrom 跟 LoadFile的差別呢? 如果我們要建立本機的組件的話,建議是使用LoadFile,因為如果你有3個RM.dll版本資料都一樣,只是Logic和放的目錄不同,如,
c:\RM\V1\RM.dll => Logic1
c:\RM\V2\RM.dll => Logic 2
c:\RM\V3\RM.dll => Logic 3
如果我們依不同的資訊同時間去建立V1~V3的RM.dll實體的話,那使用LoadFrom的話你永遠只會取到第1個建立的,如果是先建立V1的RM.dll, 那之後建立V2的RM.dll,還是會給V1的RM.dll哦!
如果用LoadFile就不會有這種情形哦!
Use the LoadFile method to load and examine assemblies that have the same identity, but are located in different paths.
另外,也有Assembly.ReflectionOnlyLoad可以用哦! 類似Assembly.Load但是如果該組件有用到其他的組件,有可能會有錯誤哦! 有人說,如果有其他的組件資訊的話,還要再Call AppDomain.ReflectionOnlyAssemblyResolve。
結論
如果要建立的DLL只有這個專案使用的話,那就放在Bin,請使用Assembly.Load
如果要建立的DLL是給多個專案使用的話,那就放在固定的地方,請使用Assembly.LoadFile
如果有特殊需求,就可以參考使用Assembly.LoadFrom
參考資源
http://www.codeproject.com/KB/vb/LoadAssembly_Games.aspx
http://www.codeproject.com/KB/dotnet/AssemblyLoadFile.aspx
http://msdn.microsoft.com/en-us/library/0et80c7k.aspx
http://stackoverflow.com/questions/305835/c-assembly-load-vs-assembly-reflectiononlyload
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^