2010-05-24 53 views
6

我們已經建立了一個小的組件,它有一個id,查找數據庫中的程序集/命名空間/類條目,並動態加載,我們是一個類的實例後。到目前爲止,它一直工作的很好,但是在VS 2010中運行此代碼時,它失敗了。問題:在.NET動態加載程序集

Private Function AssemblyLoaded(ByVal assemblyFile As String) As Assembly 
    Dim assemblies() As Assembly = AppDomain.CurrentDomain.GetAssemblies 

    For Each asmb As Assembly In assemblies 
     If (asmb.Location = assemblyFile)) Then Return asmb 
    Next 
    Return Nothing 
End Function 

的第一個問題是,當迭代器擊中一個動態裝配,沒有asmb.Location,並NotSupportedException異常被拋出。有沒有辦法檢查Location字段的Unsupported-ness而不必捕捉異常?

的第二個問題,asmb.Location改爲只返回文件名,這意味着該函數失敗每一次的完整路徑。如果此函數確定某個類尚未加載,那麼我們嘗試加載它並獲取AccessViolationException,因爲該類已經加載,我們無法「重新加載」它。

更改功能,其工作原理:

Private Function AssemblyLoaded(ByVal assemblyFile As String) As Assembly 
    Dim assemblies() As Assembly = AppDomain.CurrentDomain.GetAssemblies 

    For Each asmb As Assembly In assemblies 
     Try 
      If (asmb.Location.EndsWith(assemblyFile)) Then Return asmb 
     Catch ex As NotSupportedException 
      Continue For 
     End Try 
    Next 

    Return Nothing 
End Function 

但感覺很髒。有沒有更好的方法來檢查程序集是否已經加載,並將其返回給調用者?以上問題是針對.NET 4.0還是Visual Studio 2010?我沒有在IDE之外嘗試過,因爲它需要相當重要的配置。

回答

5

您可以檢查裝配是通過跳過AssemblyBuilder實例的動態。您應該使用Path.GetFileName()來隔離名稱。注意,這不是一個好主意,因爲來自不同路徑的程序集可能具有相同的名稱。但你似乎一直在堅持這一點。因此:

Private Function AssemblyLoaded(ByVal assemblyFile As String) As Assembly 
    For Each asmb As Assembly In AppDomain.CurrentDomain.GetAssemblies 
     If TypeOf asmb Is System.Reflection.Emit.AssemblyBuilder Then Continue For 
     If System.IO.Path.GetFileName(asmb.Location) = assemblyFile Then Return asmb 
    Next 
    Return Nothing 
End Function 

大小寫敏感性也是你應該處理的事情,也許。

+0

這工作,謝謝。爲了簡潔,我刪除了.ToLower,但我們處理區分大小寫。 – 2010-05-25 01:46:49

2

爲了增加漢斯帕桑特的前面回答:我的應用程序(C#4.0),跳繩還是失敗的AssemblyBuilder實例。原來有另一個類,System.Reflection.Emit.InternalAssemblyBuilder,訪問Location時也拋出一個NotSupportedException

InternalAssemblyBuilderRuntimeAssembly(所需的類型)都是內部的,所以最好我能想出是(在C#):

var assemblies = AppDomain.CurrentDomain 
    .GetAssemblies() 
    .Where(assembly => assembly.GetType().Name == "RuntimeAssembly") 
    .Select(assembly => assembly.Location) 
    .ToArray(); 
+1

如果您使用的是.NET 4.0,你應該檢查Assembly.IsDynamic,覆蓋所有基地 – 2015-04-02 09:14:26

+0

@DenisTroller感謝您的評論 - 你應該把它作爲一個答案:) – Jedidja 2016-12-13 16:01:36

0

如果您使用的是.NET 4.0,你應該檢查Assembly.IsDynamic,它涵蓋所有的基地...