2011-03-11 45 views
4

我使用CSharpCodeProvider編譯程序集,並且我將CompileParametersGenerateInMemory屬性設置爲true,因爲我不想創建物理文件。將InMemory編譯程序集加載到當前域

編譯後,我可以採取CompilerResults,做這樣的事情 -

object x = cr.CompiledAssembly.CreateInstance("MyGeneratedClass"); 
Console.WriteLine(x); 

我得到預期的輸出,該CreateInstance工作過。

但是,我需要能夠訪問當前AppDomain中的類型,而不必知道程序集。我需要做這樣的事情: -

Type t = Type.GetType("MyGeneratedClass"); 
object x = Activator.CreateInstance(t); 

問題是在這個代碼t結束爲空。現在我懷疑,雖然程序集已經編譯過,但沒有加載。我似乎無法找到將此程序集加載到域中,以便可以解析其類型名稱。

任何人都可以啓發我嗎?

回答

6

恐怕這是不可能的。

documentation for Type.GetType明確指出:

如果裝配尚未保存時的GetType被稱爲磁盤,該方法返回null。 GetType不理解瞬態動態程序集;因此,調用GetType來檢索瞬態動態程序集中的類型將返回null。

如果您希望它像任何常規程序集一樣運行,您必須將程序集寫入磁盤。

+0

選擇此作爲答案,因爲它使我找到正確的解決方案。 GetType中的名稱需要使用程序集名稱來定製,程序集名稱可以在CompileParameters中定義。 – AnthonyWJones 2011-03-21 13:07:38

+0

@AnthonyWJones:酷!很高興我能幫上忙。 :-) – 2011-03-21 15:03:19

5

GenerateInMemory屬性是一個會客技巧。 C#編譯器不知道如何寫入程序的內存。這是僞造的,編譯器被要求將程序集實際寫入TEMP目錄。 Assembly.Load(byte []),在編譯成功後,從FileStream將其加載到內存中。用Reflector,Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch()方法觀察一下。

由於它創建了一個文件,只是不太明顯,只要讓它創建一個文件並將其加載到AppDomain中即可解決問題。

+0

謝謝,我擺脫了GenerateInMemory,但我現在卡在如何加載程序集,我在'cr.PathToAssembly'上使用'Assembly.LoadFile'。不過,我對'GetType'的調用仍然返回null。 – AnthonyWJones 2011-03-13 21:35:04

+0

避免像瘟疫一樣Assembly.LoadFile(),總是使用LoadFrom()。請注意,您現在擁有程序集,您可以在Reflector中打開它以獲取查看。否則很難猜測爲什麼GetType不起作用。也許你忘了命名空間或者沒有公開它?另請參閱您從GetTypes()中獲得的內容。別忘了你這樣做是爲了讓它加載到另一個AppDomain中。 – 2011-03-13 21:42:05

+0

取消AppDomain的評論,我對這個問題感到困惑。在獲得它的工作之後,您可以將GenerateInMemory設置爲true。 – 2011-03-13 21:45:41

相關問題