連續(xù)兩天都為這個運行時錯誤“類型初始值設(shè)定項引發(fā)異?!倍鵁?,調(diào)試也不知道哪里出了問題。上網(wǎng)Google一下,一大堆相同的問題,可是按照那些方法折騰來折騰去,問題還是一樣。最后在CSDN上發(fā)帖子問了,果然“重賞之下必有勇夫”,很快就有高手回復(fù)了,問題也隨著解決了。哈哈。在此寫個隨筆,以后如果大家遇到類似問題,也可參考一下,自己也做個備忘,不然放在電腦上,又找不到,我的電腦文件到處亂放,有時連我自己都找不到^_^。
問題是這樣嘀:
項目采用了三層架構(gòu)和工廠模式,并借鑒了PetShop的架構(gòu),因為這個項目也是采用分布式的數(shù)據(jù)庫,目前只有三個數(shù)據(jù)庫,主要出于提高訪問性能考慮。
原來是按照網(wǎng)上對PetShop的介紹來給各項目添加引用的。
1、Web 引用 BLL。
2、BLL 引用 IDAL,Model,使用DALFactory創(chuàng)建實例。
3、IDAL 引用 Model。
在編程中,使用反射(IoC)是一個很好的架構(gòu)。在.Net中,System.Reflection命名空間提供了對反射的支持。然而,很多朋友在使用Assembly.Load()方法時,卻不能正確裝載程序集。比如,很多朋友在模仿PetShop的框架時,使用這樣的調(diào)用方式:
stringassemblyName = ConfigurationManager.AppSettings["webDAL"];
stringconstructor = ConfigurationManager.AppSettings["constructorClass"];
return (IExample)Assembly.Load(assemblyName).CreateInstance(constructor,false);
然而,在Assembly.Load()方法處,經(jīng)常出現(xiàn)未能加載程序集的錯誤:
未能加載文件或程序集“webDAL”或它的某一個依賴項。系統(tǒng)找不到指定的文件
Assembly.Load(assemblyName)實際上是在assemblyName.dll文件中查找類custructor的定義。例如,Assembly.Load("PetShop.SQLServerDAL").CreateInstance("PetShop.SQLServerDAL.Cateogry"),就是在PetShop.SQLServerDAL.dll程序集中查找PetShop.SQLServerDAL.Category類。而在自己定義類庫時,往往忽視了生成的程序集的名稱。
在類庫項目上點擊右鍵->屬性,可以設(shè)定生成的程序集的文件名。只有正確設(shè)置了,才能在Assembly.Load(assemblyName)方法中避免找不到程序集的錯誤。
錯誤描述:未能加載文件或程序集“SQLServerDAL”或它的某一個依賴項。文件不存在。
原因:1.在利用分層設(shè)計思想開發(fā)時,關(guān)于動態(tài)反射的理解不清晰。
2.由于開發(fā)工具的bug問題,造成未能加載程序集。
解決方案:
1.反射編程要求在網(wǎng)站的Bin文件夾中有已經(jīng)編譯好的.DLL文件(即保持DLL文件存在),并且保持名稱和編譯前類庫的名稱一致。可稱:添加引用性。
2.查看網(wǎng)站中的項目(類庫)屬性,確認(rèn)是否默認(rèn)命名空間和程序集名稱以及Bin文件夾下的DLL文件名稱是否一致,不一致則會出現(xiàn)未能加載文件或者程序集,所以的修改項目的屬性??煞Q:名稱一致性。
3.建議在編程的時在創(chuàng)建類庫的時候?qū)懮舷到y(tǒng)名稱+項目名稱,能夠有效的避免Bug產(chǎn)出。即:SystemName.Model或者SystemName.IDAL。eg:BBS.Model??煞Q:名稱完整性。
Assembly.Load(path) 其中這個path是加載你項目web下bin目錄的程序集,也就是說你要反射的程序集在你的web的bin下一定要有,看看你引用沒有呢????
4、Model 無引用。
5、DALFactory 引用IDAL,通過讀取web.config里設(shè)置的程序集,加載類的實例,返回給BLL使用。
6、SQLServerDAL 引用 Model和IDAL,被DALFactory加載的程序集,實現(xiàn)接口里的方法。
問題就出在這里了。頂!
按照PetShop的架構(gòu),是DALFactory程序集里通過反射創(chuàng)建針對特定數(shù)據(jù)訪問層里的對應(yīng)類實例,這樣BLL調(diào)用接口時就知道調(diào)用這個對應(yīng)類實例里的實現(xiàn)方法。
而反射動態(tài)加載程序集是通過這種方法 Assembly.Load("程序集").CreateInstance("命名空間.類"),其中的“程序集”讀取的是Web層bin文件夾下對應(yīng)的dll,即反射加載的程序集dll在Web層的bin文件夾必須有,不然就會出現(xiàn)如題的錯誤。問題解決了~^_^
出現(xiàn)這種錯誤的另兩種情況,這也是在網(wǎng)上看到的,一起寫下來。
一、Web.config配置錯誤。
在DALFactory程序集里的DataAccess類里,通過
private static readonly string path =ConfigurationManager.AppSettings["WebDAL"];
來獲得程序集的名稱的。
在Web.config里我的配置如下:
<appSettings>
<add key="WebDAL" value="PDMS.SQLServerDAL"/>
</appSettings>
二、程序集名稱和默認(rèn)命名空間錯誤。
在各個程序集右鍵--屬性,看看程序集名稱和默認(rèn)命名空間有沒有寫錯。這個問題也可能導(dǎo)致如題的錯誤~~
第一次用反射,就出了這個問題,學(xué)到不少,還得加深對反射的理解^_^