2011-11-04 32 views
7

我使用下面的代碼:如何從另一個文件夾中加載的程序集中獲取類型?

Assembly.LoadFile("the assembly in another folder"); 
var type = Type.GetType("the full name of the type"); 

即使組件這行代碼之前就已經加載,它總是返回null在type。 PS:我沒有通過程序集限定名稱,包括名稱空間,類型名稱,程序集名稱,版本和公共令牌。

+0

這是'assembly'主題相關的彙編語言? –

+0

@KirilKirov:不。它是.Net中的一種類型。 –

+0

@奧斯汀 - 啊,謝謝:)我被標籤誤導了。 –

回答

9

Type.GetType只搜索調用程序集中的類型和mscorlib.dll中的類型,除非您傳遞該類型的程序集限定名稱。 See here.

編輯

看來,Type.GetType只能夠從Load上下文組件檢索Type實例。使用LoadFile加載的程序集位於no context中,使用LoadFrom加載的程序集位於加載來源上下文中;這些上下文都不允許您使用Type.GetType,因此分辨率會失敗。 This article顯示Type信息可以在Assembly當它所在的目錄被添加爲探測私有路徑時被檢索到,因爲它最終將在負載上下文中結束,但在其他上下文中將失敗。

+0

我沒有傳入程序集限定名稱,包括名稱空間,類型名稱,程序集名稱和版本,公共標記。 – CuiPengFei

+0

@CuiPengFei只是爲了消除明顯的,你可以肯定,裝配合格的名稱完全區分大小寫的值,如果你靜態引用大會,並呼籲'typeof運算(類型名).AssemblyQualifiedName',你會得到相匹配? –

+0

是的,我確定。 – CuiPengFei

1

你可以試試這個....

Assembly.GetAssembly假設你有類型的實例,並Type.GetType假設你有完全限定的類型名稱,其中包括程序集名稱。

你可以給組件位於路徑.....

如果只有基本類型名稱,你需要做更多的東西是這樣的:

public static String GetAssemblyNameContainingType(String typeName) 
{ 
    foreach (Assembly currentassembly in AppDomain.CurrentDomain.GetAssemblies()) 
    { 
     Type t = currentassembly.GetType(typeName, false, true); 
     if (t != null) {return currentassembly.FullName;} 
    } 

    return "not found"; 
} 

這也假定您類型在根中聲明。您需要在名稱中提供名稱空間或封裝類型,或者以相同的方式進行迭代。

+0

加載程序集時要小心,因爲一旦將它們加載到AppDomain中,就無法卸載它們了。如果你有很多需要加載的程序集,請考慮創建單獨的AppDomain,它將完成處理程序集和返回結果的工作,之後可以發佈它。 –

+0

我不會推薦這個。取而代之的是,結合到[AppDomain.AssemblyResolve](http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyload.aspx)事件。這樣,你只返回所需的程序集,在上面的代碼中,你搜索_each和每個加載的程序集,再加上你現在不需要的加載程序。 – Abel

2

做的最簡單的方式就是陷阱Assembly.LoadFile的返回值的變量,並調用的GetType它是這樣的:

Assembly assem = Assembly.LoadFile("assemblyLocation"); 
assem.GetType("typeName"); 

你可能要考慮保持參照本次大會如果你想要經常從其中抽取類型,或者做其他人的建議,並製作一個更加通用的方法來遍歷所有加載的程序集。

4

對於不在加載上下文中但在加載或無上下文環境中的程序集中的類型必須使用Type.GetType(string)的「正確」(MS推薦)方法,要綁定到Appdomain.AssemblyResolve事件。以下代碼是相對有效的:

// this resolver works as long as the assembly is already loaded 
// with LoadFile/LoadFrom or Load(string)/Load(byte[]) 
private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) 
{ 
    var asm = (from a in AppDomain.CurrentDomain.GetAssemblies() 
       where a.GetName().FullName == args.Name 
       select a).FirstOrDefault(); 

    if(asm == null) 
     throw FileNotFoundException(args.Name);  // this becomes inner exc 

    return asm; 
} 

// place this somewhere in the beginning of your app: 
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; 

似乎稍微更有效地創建AssemblyLoad /解決事件的組合來保持加載的程序集的一個字典(使用組件-名作爲關鍵字)。

正在裝配。的LoadFile
有使用這種方法的一些嚴重的缺陷。 According to MSDN

與LoadFrom方法一樣,LoadFile不會將文件加載到LoadFrom上下文中,也不會使用加載路徑解析依賴項。

因此,如果可能的話,不使用的LoadFile。生成的程序集將加載到無上下文環境中,該環境比來自上下文的負載具有更多的缺點。相反,使用Assembly.LoadFrom並且依賴關係將從加載路徑自動加載。

相關問題