閱讀679 返回首頁    go 阿裏雲 go 技術社區[雲棲]


工廠模式的Assembly.Load(path).CreateInstance(className)出錯解決方法

 1、問題描述

  代碼展示

  下麵是Factory中的一段代碼: 

'**********************************************
' 文 件 名:DataAcess
' 命名空間:Factory
' 內    容:
' 功    能:創建用戶需要的接口
' 文件關係:
' 作    者:令仔很忙
' 小    組:
' 生成日期:2014-07-28 17:37:52
' 版 本 號:V2.0
' 修改日誌:
' 版權說明:
'**********************************************
Imports System.Reflection             '引用 反射 命名空間
Imports System .Configuration 
Public Class DataAcess
    Private Shared ReadOnly assemblyName As String = "DAL"   '數據程序集名稱
    Dim strDB As String = System.Configuration.ConfigurationSettings.AppSettings("DB")
    ''' <summary>
    ''' 創建用戶接口
    ''' </summary>
    ''' <returns>返回IUser</returns>
    ''' <remarks></remarks>
    Public Function CreateIUser() As IDAL.IUser
        Dim className As String = assemblyName + "." + strDB + "UserDAL"      '定義  命名空間.類
<pre name="code" ><span >	</span>Return CType(Assembly.Load(assemblyName).CreateInstance(className), IDAL.IUser)      ’容易出錯不易理解的地方


在這段代碼中,下麵這一語句是不易理解,容易出錯的地方

Return CType(Assembly.Load(assemblyName).CreateInstance(className), IDAL.IUser)         
   

  相關知識了解

  下麵咱們先了解Assembly.Load(path).CreateInstance(className)  

  在VB.NET中,我們要使用反射,首先要搞清楚以下命名空間中幾個類的關係: 
  System.Reflection命名空間
  (1)  AppDomain:應用程序域,可以將其理解為一組程序集的邏輯容器
  (2)  Assembly:程序集類
  (3)  Module:模塊類
  (4)  Type:使用反射得到類型信息的最核心的類


  他們之間是一種從屬關係,也就是說,一個AppDomain可以包含N個Assembly,一個Assembly可以包含N個Module,而一個Module可以包含N個Type.


  在上麵的語句中我們用到的是Assembly這一類,在程序中,如果我們要動態加載一個程序集怎麼辦呢?有幾種方式可以使用,分別是Load,LoadFrom和LoadWithPartialName三個Assembly的靜態方法.我們主要說Load方法:   

  

  Assembly.Load("")的使用說明如下;  
  並不是命名空間。常用的是程序集名稱,也就是dll的名稱  
  重載列表    
  名稱說明 
  Assembly.Load(AssemblyName)在給定程序集的AssemblyName的情況下,加載程序集。


2、 出現的問題及解決方法

  未能加載文件或程序集“DAL”或它的某一個依賴項,係統找不到指定文件

    關於反射Assembly.Load("程序集").CreateInstance("命名空間."),而不管在哪一層寫這段代碼其中的("程序集")讀取的實際是webbin文件夾下的dll,也就是說你反射的類的程序集dllweb層的bin下必須有。

    注意CreateInstance()一定是命名空間.類名,否則創建的實例為空

    Assembly.Load("程序集名")

    

    出現這樣的錯誤有三種可能:

    1)、DLL文件名與加載時的DLL文件名不一致。
    2)、.DLL文件根本不存在,即出現丟失情況。
    3)、加載DLL路徑錯誤,即DLL文件存在,但加載路徑不正確

   看了下自己的問題,主要就是上麵的第三種情況,加載路徑不正確,怎麼解決?

    找到文件夾DAL/bin/Debug,將裏麵與DAL相關的文件複製到UI/bin/Debug中去,運行,就可以了,後期的工作,如果每次遇到這中情況都手動添加的話會很麻煩,所以我們需要更改程序的生成路徑:

    


  未將對象引用設置到對象的實例

    上麵的語句中的CreateInstance(className),中className其實是需要反射的類型全名(包括命名空間的全路徑),如下圖:最終className返回的結果是DAL.SqlUserDAL

  

它是和DAL層相對應的,所以DAL層下的類的命名必須和它保持一致


其實這個問題有很多種情況,這隻是其中的一種出錯的地方和解決方法。


3、結束語

  機房收費係統重構,剛開始開始敲三層或者開始敲七層,都是一段困難的過程,但是在這個過程中也是你進步最大的,不會了,多看看其他人的博客,多問,不理解可以先把別人的拿過來用,魯迅先生在《拿來主義》中說過一句話:“有選擇的拿,為我所用的拿,不卑不亢的拿”。借鑒是豁然開朗,是一種共鳴,為我所用,有更上一層樓的感覺;照抄是模仿,但走不出去,就會失去自我,如果說有臨界點的話,那就是我說我的話,用自己的話別人能聽懂而已。

    

 

    



  

  

最後更新:2017-04-03 05:39:34

  上一篇:go android開發階段性技能
  下一篇:go 九度題目1153:括號匹配問題