2009-04-29 35 views
1

我有一個ASP.net應用程序引用一個外部程序集,我需要動態加載並發現實​​現已知接口的任何類型。我遇到的問題是,我反映的類型與正在運行的接口不匹配,因此我無法投射它。在ASP.net環境下反映的問題

實施例:

該代碼在ASP.net應用運行。

var assembly = Assembly.LoadFile(Path.Combine(HttpRuntime.BinDirectory, "ExternalAssembly.dll")); 

var type = assembly.GetExportedTypes().First<Type>(x => x.Name == "AClass"); // AClass implements IAInterface 

var reflectedInterface = type.GetInterface(typeof(IAmAInterface).ToString()); 

if (reflectedInterface != typeof(IAmAInterface)) 
    throw new Exception("This makes me sad"); // This code gets run 

我可以我從料箱和所述接口從typeof運算返回加載的反射界面之間看到的唯一區別是,將typeof組件具有在臨時ASP.net路徑(C的位置:\ Windows \微軟.NET \ Framework \ v2.0.50727 \ Temporary ASP.NET Files \ root \ 08c43c8b \ 3adac8cf \ assembly \ dl3 \ eb7a4127 \ 0235ea60_a3c8c901 \ ReflectionTest.DLL)

感謝Paul Alexander我更改了使用Assembly的代碼。 Load方法不是Assembly.LoadFile,它解決了這個問題。

wwilden:我也嘗試提取接口到它自己組裝,這是否也是解決問題。

回答

2

當您使用的LoadFile的組件沒有加載到相同的上下文在運行時你的其他組件,以便於CLR接口運行的類型是不同的。你可以閱讀Suzanne Cook的Debugging Assembly Load Failures

如果你加載程序集已經在Bin目錄 - 您可以通過名稱加載它。因爲Bin文件夾已經在裝配探測路徑中,所以不需要知道確切的路徑。

1

您的接口類型在哪裏定義?它既存在於反射組件中,也存在於應用程序本身中?然後你實際上有兩個不同的接口,即使它們有相同的名稱空間和名稱。

你需要做的是提取反射組件的接口,並把它放進你從反射組件以及應用程序一併參照其他組件。那麼它應該工作。

0
從您的問題

除此之外,如果你有很多組件的動態加載,請記住,他們將保留在內存中,直到ASP.NET工作進程重新加載。這可能會影響您的服務器的性能。

你可以加載在一個單獨的AppDomain(這是可能卸載的最小單位)的組件,在其中與.NET遠程引用的AppDomain加載代理類。完成後,您卸載AppDomain。

0

There is an interesting article over at CodeProject關於這樣的情況。如果你有一個類沒有實現接口本身的結構與接口相同。本文概述了一種動態創建實現所需接口的包裝類的方法。這可能對您的情況有所幫助。