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