다음을 통해 공유


System.Reflection.Emit.AssemblyBuilder 클래스

이 문서에서는 이 API에 대한 참조 설명서에 대한 추가 설명서를 제공합니다.

동적 어셈블리는 리플렉션 내보내기 API를 사용하여 만든 어셈블리입니다. 동적 어셈블리는 다른 동적 또는 정적 어셈블리에 정의된 형식을 참조할 수 있습니다. 동일한 애플리케이션을 실행하는 동안 메모리에서 동적 어셈블리를 생성하고 해당 코드를 실행하는 데 사용할 AssemblyBuilder 수 있습니다. .NET 9에서는 어셈블리를 파일에 저장할 수 있도록 완전히 관리되는 리플렉션 내보내기 구현이 포함된 새로운 PersistedAssemblyBuilder 를 추가했습니다. .NET Framework에서 동적 어셈블리를 실행하고 파일에 저장하여 둘 다 수행할 수 있습니다. 저장을 위해 만든 동적 어셈블리를 지속형 어셈블리라고 하지만 일반 메모리 전용 어셈블리를 일시적 또는 실행 가능 어셈블리라고 합니다. .NET Framework에서 동적 어셈블리는 하나 이상의 동적 모듈로 구성됩니다. .NET Core 및 .NET 5 이상에서는 동적 어셈블리가 하나의 동적 모듈로만 구성됩니다.

인스턴스를 AssemblyBuilder 만드는 방법은 각 구현마다 다르지만 모듈, 형식, 메서드 또는 열거형을 정의하고 IL을 작성하는 추가 단계는 매우 유사합니다.

.NET에서 실행 가능한 동적 어셈블리

실행 가능한 AssemblyBuilder 개체를 얻으려면 메서드를 AssemblyBuilder.DefineDynamicAssembly 사용합니다. 동적 어셈블리는 다음 액세스 모드 중 하나를 사용하여 만들 수 있습니다.

동적 어셈블리가 정의되고 나중에 변경할 수 없는 경우 메서드 호출 AssemblyBuilder.DefineDynamicAssembly 에 적절한 AssemblyBuilderAccess 값을 제공하여 액세스 모드를 지정해야 합니다. 런타임은 동적 어셈블리의 액세스 모드를 사용하여 어셈블리의 내부 표현을 최적화합니다.

다음 예제에서는 어셈블리를 만들고 실행하는 방법을 보여 줍니다.

public void CreateAndRunAssembly(string assemblyPath)
{
    AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("MyAssembly"), AssemblyBuilderAccess.Run);
    ModuleBuilder mob = ab.DefineDynamicModule("MyModule");
    TypeBuilder tb = mob.DefineType("MyType", TypeAttributes.Public | TypeAttributes.Class);
    MethodBuilder mb = tb.DefineMethod("SumMethod", MethodAttributes.Public | MethodAttributes.Static,
                                                                   typeof(int), new Type[] {typeof(int), typeof(int)});
    ILGenerator il = mb.GetILGenerator();
    il.Emit(OpCodes.Ldarg_0);
    il.Emit(OpCodes.Ldarg_1);
    il.Emit(OpCodes.Add);
    il.Emit(OpCodes.Ret);

    Type type = tb.CreateType();

    MethodInfo method = type.GetMethod("SumMethod");
    Console.WriteLine(method.Invoke(null, new object[] { 5, 10 }));
}

.NET의 지속형 동적 어셈블리

.NET Core에서 AssemblyBuilder 파생되고 동적 어셈블리를 저장할 수 있는 새 PersistedAssemblyBuilder 형식으로, PersistedAssemblyBuilder 페이지의 사용 시나리오 및 예제를 검사.

.NET Framework의 지속형 동적 어셈블리

.NET Framework에서 동적 어셈블리 및 모듈을 파일에 저장할 수 있습니다. 이 기능을 지원하기 위해 열거형은 AssemblyBuilderAccess 두 개의 추가 필드를 SaveRunAndSave선언합니다.

지속 가능한 동적 어셈블리의 동적 모듈은 메서드를 사용하여 Save 동적 어셈블리를 저장할 때 저장됩니다. 실행 파일을 생성하려면 어셈블리의 SetEntryPoint 진입점인 메서드를 식별하기 위해 메서드를 호출해야 합니다. 어셈블리는 Dll로 기본적으로 저장 하지 않는 한를 SetEntryPoint 메서드 요청 콘솔 애플리케이션 또는 Windows 기반 애플리케이션을 생성 합니다.

다음 예제에서는 .NET Framework를 사용하여 어셈블리를 만들고 저장하고 실행하는 방법을 보여 줍니다.

public void CreateRunAndSaveAssembly(string assemblyPath)
{
    AssemblyBuilder ab = Thread.GetDomain().DefineDynamicAssembly(new AssemblyName("MyAssembly"), AssemblyBuilderAccess.RunAndSave);
    ModuleBuilder mob = ab.DefineDynamicModule("MyAssembly.dll");
    TypeBuilder tb = mob.DefineType("MyType", TypeAttributes.Public | TypeAttributes.Class);
    MethodBuilder meb = tb.DefineMethod("SumMethod", MethodAttributes.Public | MethodAttributes.Static,
                                                                   typeof(int), new Type[] {typeof(int), typeof(int)});
    ILGenerator il = meb.GetILGenerator();
    il.Emit(OpCodes.Ldarg_0);
    il.Emit(OpCodes.Ldarg_1);
    il.Emit(OpCodes.Add);
    il.Emit(OpCodes.Ret);

    Type type = tb.CreateType();

    MethodInfo method = type.GetMethod("SumMethod");
    Console.WriteLine(method.Invoke(null, new object[] { 5, 10 }));
    ab.Save("MyAssembly.dll");
}

개체에서 AssemblyBuilder 호출할 때 기본 Assembly 클래스와 GetLoadedModules같은 GetModules 일부 메서드가 제대로 작동하지 않습니다. 정의된 동적 어셈블리를 로드하고 로드된 어셈블리에서 메서드를 호출할 수 있습니다. 예를 들어 리소스 모듈이 반환된 모듈 목록에 포함되도록 하려면 로드된 Assembly 개체를 호출 GetModules 합니다. 동적 어셈블리에 둘 이상의 동적 모듈이 포함된 경우 어셈블리의 매니페스트 파일 이름은 메서드의 첫 번째 인수 DefineDynamicModule 로 지정된 모듈의 이름과 일치해야 합니다.

사용 하 여 KeyPair 동적 어셈블리의 서명은 어셈블리 디스크에 저장 될 때까지 유효 하지 않습니다. 따라서 강력한 이름은 일시적인 동적 어셈블리에서 작동하지 않습니다.

동적 어셈블리는 다른 어셈블리에 정의된 형식을 참조할 수 있습니다. 임시 동적 어셈블리는 다른 임시 동적 어셈블리, 지속 가능한 동적 어셈블리 또는 정적 어셈블리에 정의된 형식을 안전하게 참조할 수 있습니다. 그러나 공용 언어 런타임에서는 지속 가능한 동적 모듈이 일시적인 동적 모듈에 정의된 형식을 참조할 수 없습니다. 이는 지속형 동적 모듈이 디스크에 저장된 후 로드될 때 런타임에서 일시적인 동적 모듈에 정의된 형식에 대한 참조를 확인할 수 없기 때문입니다.

원격 애플리케이션 도메인에 내보내기에 대 한 제한

일부 시나리오에는 동적 어셈블리를 생성 하 고 원격 애플리케이션 도메인에서 실행 해야 합니다. 리플렉션 내보내기 동적 어셈블리를 원격 애플리케이션 도메인에 직접 내보낼 수 없도록 합니다. 솔루션이 현재 애플리케이션 도메인에서 동적 어셈블리를 내보내고 내보낸된 동적 어셈블리를 디스크에 저장 하 고 다음 원격 애플리케이션 도메인에 동적 어셈블리를 로드 하는 것입니다. 원격 및 애플리케이션 do기본s는 .NET Framework에서만 지원됩니다.