私はC#で中間言語(IL)の生成を教えていますが、私は、例えばSystem.Windows.Forms.dll
(たとえば)を参照する方法について、時間のように思っていましたhttp://olondono.blogspot.com/2008/02/creating-code-at-runtime.html動的に生成されたアセンブリからGACアセンブリを参照する方法はありますか?
で最も優れた-例に基づいて、私はAppDomain.CurrentDomain.DefineDynamicAssembly
とSystem.Reflection.Emit
を使用して生成してい動的アセンブリは、...私は基本的なTransferObjectDllGeneratorの作業を持っているが、今私はから既存のライブラリを参照したいのですが(のみ)生成されたアセンブリ内で、どのように把握することはできません。
This SO question私をAppDomain.CurrentDomain.AssemblyResolve
イベントに導いてください。私はイベントハンドラを実装しようとしましたが、それは決してトリガされていないので、間違った場所にイベントハンドラを置くなど、
正しい方向へのポインタがあれば幸いです。
あなたは/がTransferObjectDllGeneratorコードが叫ぶくださいしたい必要がある場合、それは(私見)少し大きすぎるので、ここに私のメインラインの...興味深いビットが// <<-- 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
です...私はそれを投稿していませんフォーラムのポストのために。
お時間をいただきありがとうございます。
乾杯。キース。
EDIT:将来的にこのスレッドを見つけた人のための作業例を提供します。
カスタムの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