저는 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
입니다 ... 너무 큰 비트 (IMHO)이 있기 때문에 나는 그것을 게시하지 않은 포럼 게시물에 대한.
미리 감사드립니다.
건배. 키이스.
편집
: 향후이 스레드를 찾는 사람을위한 작업 예제를 제공한다.사용자 지정 AssemblyResolve
이벤트 처리기를 제공 할 필요가 없습니다. 그것은 phurphy입니다. 어셈블리 이름, 네임 스페이스, 버전 및 GUID가있는 어셈블리의 정규화 된 이름을 제공하면됩니다. 는 현재 어셈블리 및 mscorlib에있는 유형 이름을 검색합니다 지정된 어셈블리 이름이없는
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
감사합니다. 줄리앙, 그게 내가 누락 된 것입니다 ... 지금 코드를 업데이트하여 효과가있는 것을 보여 드리겠습니다. – corlettk