我在教自己C#中的中間語言(IL)生成,我一直堅持幾個小時,看起來像天,如何從System.Windows.Forms.dll
(例如)從動態程序,其中我使用AppDomain.CurrentDomain.DefineDynamicAssembly
和System.Reflection.Emit
產生...基於最優,例如在http://olondono.blogspot.com/2008/02/creating-code-at-runtime.html如何從動態生成的程序集中引用GAC程序集?
我已經有了一個基本的TransferObjectDllGenerator工作,但現在我想引用從現有的庫(僅)在生成的程序集中,並且無法弄清楚。
This SO question將我引向AppDomain.CurrentDomain.AssemblyResolve
事件。我嘗試實現一個事件處理程序,但它從來沒有觸發,所以我想我已經做了一些基本愚蠢的事情,比如把事件處理程序放在完全錯誤的地方?
任何指針在正確的方向將不勝感激。
這裏是我的主線......有趣的位是// <<-- Commented thus
using System;
using System.Reflection;
//using System.Windows.Forms; (and removed the project's Reference to System.Windows.Forms)
namespace ILGen
{
/// <summary>
/// Generates .\bin\$whatever\PersonLibrary.dll containing MSIL equivalent to:
/// namespace PersonLibrary {
/// public class Person {
/// public string FirstName { get; set; }
/// public string LastName { get; set; }
/// public Person() { }
/// public Person(string firstname, string lastname) {
/// FirstName = firstname;
/// LastName = lastname;
/// }
/// } //end-class
/// } //end-namespace
/// </summary>
public class Program
{
public static void Main(String[] args) {
AppDomain.CurrentDomain.AssemblyResolve += MyAssemblyResolver; // <<-- Hook the "resolve this assembly" event.
try {
var dll = new TransferObjectDllGenerator("PersonLibrary");
dll.AddClass("Person", new[] {
new Property("FirstName", typeof(string))
, new Property("LastName", typeof(string))
, new Property("OK", Type.GetType("System.Windows.Forms.Button")) // <<-- References System.Windows.Forms.dll; Type.GetType returns null.
});
Console.WriteLine("Generated: " + dll.Save());
} finally {
AppDomain.CurrentDomain.AssemblyResolve -= MyAssemblyResolver; // <<-- Unhook the "resolve this assembly" event.
}
}
static Assembly MyAssemblyResolver(object sender, ResolveEventArgs args) // <<-- Handle the "resolve this assembly" event.
{
if (args.Name.StartsWith("System.Windows.Forms.")) // <<-- Breakpoint here, which is never reached.
return Assembly.LoadFrom(@"C:\Windows\winsxs\msil_system.windows.forms_b77a5c561934e089_6.0.6001.22230_none_1a2132e45d2f30fc\System.Windows.Forms.dll");
return null;
}
} // end-class
} // end-namespace
如果您需要/想TransferObjectDllGenerator代碼請喊......因爲這是一個有點過大(恕我直言)我還沒貼吧爲論壇帖子。
提前感謝您的時間。
乾杯。基思。
編輯:提供的人誰在將來發現這個線程的工作示例。
沒有必要提供自定義的AssemblyResolve
事件處理程序。那是一個phurphy。我們只需要提供程序集的完全限定名稱以及程序集名稱,名稱空間,版本和GUID。
using System;
using System.Reflection;
namespace ILGen
{
public class Program
{
public static void Main(String[] args) {
var dll = new TransferObjectDllGenerator("PersonLibrary");
// We need to provide the fully-qualified-assembly-name to
// make the standard assembly-resolver search the GAC.
// Thanks to Julien Lebosquain for pointing this out.
Type buttonType = Type.GetType(
"System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
dll.AddClass("Person", new[] {
new Property("FirstName", typeof(string))
, new Property("LastName", typeof(string))
, new Property("OK", buttonType)
});
Console.WriteLine("Generated: " + dll.Save());
}
} // end-class
} // end-namespace
謝謝Julien,那正是我所缺少的......我現在更新代碼以顯示工作。 – corlettk