應用反射+設定檔+抽象工廠時出現的錯誤和原因分析

來源:互聯網
上載者:User

標籤:style   blog   http   color   strong   檔案   

    先來看一段程式:

<pre name="code" class="vb">Imports System.Configuration    '設定檔命名空間Imports System.Reflection       '反射命名空間Imports IDAL                    '引用介面層Public Class DataAccess    '程式集名稱(同時代表命名空間名稱):DAL    Private Shared ReadOnly AssemblyName As String = System.Configuration.ConfigurationManager.AppSettings("assname")    '資料庫類型:Sql    Private Shared ReadOnly db As String = System.Configuration.ConfigurationManager.AppSettings("DB")    '建立D層類SqlUserInfoDAL的執行個體    Public Shared Function CreateUserInfo() As IDAL.IUserInfo        Dim dalUserInfoName As String = AssemblyName & "." & db & "UserInfoDAL"        '要執行個體化的D層類的名稱        Return CType(Assembly.Load(AssemblyName).CreateInstance(dalUserInfoName), IUserInfo)    End Function


    對於學過反射+設定檔+抽象工廠實現資料訪問的人來說,這小段程式還是很容易理解的。我將這段程式用在了機房收費系統個人重構版中。:

    但是在運行過程中卻報了錯:

    未能負載檔案或程式集“DAL”或它的某一個依賴項。系統找不到指定檔案。

    通過查資料,知道了一種解決方案:將DAL層的DAL.dll檔案複製到UI層相應的目錄下,。

    之後,程式正常運行,並通過CreateUserInfo()建立出了SqlUserInfoDAL的執行個體。

    有了成功的經驗,我便做了如下操作:

  • 在DAL層,添加了一個新的類:SqlWorkLogDAL
  • 在DataAccess中,添加了一個新的方法:CreateWorkLog()

    如下所示:

 '建立D層類SqlWorkLogDAL的執行個體    Public Shared Function CreateWorkLog() As IDAL.IWorkLog        Dim dalWorkLogName As String = AssemblyName & "." & db & "WorkLogDAL"          '要執行個體化的D層類的名稱        Return CType(Assembly.Load(AssemblyName).CreateInstance(dalWorkLogName), IWorkLog)    End Function

    但是運行後,還是報了錯,不過這次錯誤不一樣:

    未將對象引用設定到對象的執行個體。

    通過查資料,也找到了答案:修改DAL層--屬性--編譯--產生輸出路徑,將產生輸出路徑改到UI層\bin\Debug檔案夾下。

    雖然兩種解決方案不一樣,但是本質都是把DAL層的DAL.dll檔案放到UI層

    那麼,為什麼第一種解決方案只有“短暫療效”,而第二種方法可以“根治”呢?

    這時,我做了個嘗試,我不去修改路徑,而是再次把DAL層中的DAL.dll檔案複製並替換我剛才複製到UI層的檔案。

    結果成功了。

    這就說明了:兩次複製的檔案並非同一個檔案,雖然它們都叫DAL.dll,但是在檔案內部,它們一定發生了變化。

這裡我們就要說說,dll檔案是怎麼產生的了。

    每個程式集下面都有兩個檔案夾bin和obj,


    bin目錄用來儲存項目產生後程式集,obj目錄用來儲存編譯結果。編譯是分模組進行的,編譯整個完成後會合并為一個.dll或.exe檔案儲存到bin目錄下。而且採用增量編譯的方式。

    所以,當我添加了一個新的類SqlWorkLogDAl後,產生的DAL.dll已經不是原來的DAL.dll了。

    複製的方式的缺陷在於:只要DAL層發生變化,就得通過手動複製來更新U層的DAL.dll檔案。但是修改路徑,就不用我們管了,它會自動將最新的DAL.dll檔案產生到UI層。

    那麼為什麼要把D層的.dll檔案在U層產生呢?

     這就要知道Assembly.Load()是怎麼定位程式集了?

     當你只給定程式集名稱時,如“DAL”,那麼CLR只會在應用程式的目錄下尋找,而咱們的應用程式在UI層,所以要在U層有DAL.dll。

    問題又來了:

    在U層,有Entity.dll,有BLL.dll,有DataAccess.dll……為什麼就是沒有DAL.dll,為什麼只有它需要修改產生路徑?

     這裡就要看看程式的包圖了:


    ---->代表依賴,也表示引用,那麼從UI層看,UI層可以直接或間接地引用Facade層,BLL層,DataAccess層,IDAL層,但是沒有引用DAL層,所以別的層的.dll檔案會出現在U層,而DAL層的.dll檔案沒有出現在U層。

    文章中,如果有理解得不對的地方,還請大家批評指正。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.