項目采用了三層架構和工廠模式,並借鑒了PetShop的架構,因為這個項目也是采用分布式的數據庫,目前只有三個數據庫,主要出於提高訪問性能考慮。
原來是按照網上對PetShop的介紹來給各項目添加引用的。
1、Web 引用 BLL。
2、BLL 引用 IDAL,Model,使用DALFactory創建實例。
3、IDAL 引用 Model。
在編程中,使用反射(IoC)是一個很好的架構。在.Net中,System.Reflection命名空間提供了對反射的支持。然而,很多朋友在使用Assembly.Load()方法時, 卻不能正確裝載程序集。比如,很多朋友在模仿PetShop的框架時,使用這樣的調用方式:
string assemblyName = ConfigurationManager.AppSettings["webDAL"];
string constructor = ConfigurationManager.AppSettings["constructorClass"];
return (IExample)Assembly.Load(assemblyName).CreateInstance(constructor, false);
然而,在Assembly.Load()方法處,經常出現未能加載程序集的錯誤:
未能加載文件或程序集“webDAL”或它的某一個依賴項。系統找不到指定的文件
Assembly.Load(assemblyName)實際上是在assemblyName.dll文件中查找類custructor的定義。例如,Assembly.Load("PetShop.SQLServerDAL").CreateInstance("PetShop.SQLServerDAL.Cateogry"),就是在PetShop.SQLServerDAL.dll程序集中查找PetShop.SQLServerDAL.Category類。而在自己定義類庫時,往往忽視了生成的程序集的名稱。
在類庫項目上點擊右鍵->屬性,可以設定生成的程序集的文件名。只有正確設置了,才能在Assembly.Load(assemblyName)方法中避免找不到程序集的錯誤。
錯誤描述:未能加載文件或程序集“SQLServerDAL”或它的某一個依賴項。文件不存在。
原因:1.在利用分層設計思想開發時,關於動態反射的理解不清晰。
2.由於開發工具的bug問題,造成未能加載程序集。
解決方案:
1.反射編程要求在網站的Bin文件夾中有已經編譯好的.DLL文件(即保持DLL文件存在),並且保持名稱和編譯前類庫的名稱一致。可稱:添加引用性。
2.查看網站中的項目(類庫)屬性,確認是否默認命名空間和程序集名稱以及Bin文件夾下的DLL文件名稱是否一致,不一致則會出現未能加載文件或者程序集,所以的修改項目的屬性。可稱:名稱一致性。
3.建議在編程的時在創建類庫的時候寫上系統名稱+項目名稱,能夠有效的避免Bug產出。即:SystemName.Model或者SystemName.IDAL。eg:BBS.Model。可稱:名稱完整性。
Assembly.Load(path) 其中這個path是加載你項目web下bin目錄的程序集,也就是說你要反射的程序集在你的web的bin下一定要有,看看你引用沒有呢????
4、Model 無引用。
5、DALFactory 引用IDAL,通過讀取web.config里設置的程序集,加載類的實例,返回給BLL使用。
6、SQLServerDAL 引用 Model和IDAL,被DALFactory加載的程序集,實現接口里的方法。
問題就出在這里了。頂!
按照PetShop的架構,是DALFactory程序集里通過反射創建針對特定數據訪問層里的對應類實例,這樣BLL調用接口時就知道調用這個對應類實例里的實現方法。
而反射動態加載程序集是通過這種方法 Assembly.Load("程序集").CreateInstance("命名空間.類"),其中的“程序集”讀取的是Web層bin文件夾下對應的dll,即反射加載的程序集dll在Web層的bin文件夾必須有,不然就會出現如題的錯誤。問題解決了~^_^
出現這種錯誤的另兩種情況,這也是在網上看到的,一起寫下來。
一、Web.config配置錯誤。
在DALFactory程序集里的DataAccess類里,通過
private static readonly string path = ConfigurationManager.AppSettings["WebDAL"];
來獲得程序集的名稱的。
在Web.config里我的配置如下:
<appSettings>
<add key="WebDAL" value="PDMS.SQLServerDAL"/>
</appSettings>
二、程序集名稱和默認命名空間錯誤。
在各個程序集右鍵--屬性,看看程序集名稱和默認命名空間有沒有寫錯。這個問題也可能導致如題的錯誤~~
第一次用反射,就出了這個問題,學到不少,還得加深對反射的理解(本文借鑒偉人的,用來方便自己學習,別無它意)