MetadataBuilder Класс

Определение

Класс MetadataBuilder записывает метаданные для сборки высокопроизводительным способом. Он предназначен для использования компиляторами и другими средствами создания сборок.

public ref class MetadataBuilder sealed
public sealed class MetadataBuilder
type MetadataBuilder = class
Public NotInheritable Class MetadataBuilder
Наследование
MetadataBuilder

Примеры

В этом примере показано, как создать сборку консольного приложения с помощью MetadataBuilder:

private static readonly Guid s_guid = new Guid("87D4DBE1-1143-4FAD-AAB3-1001F92068E6");
private static readonly BlobContentId s_contentId = new BlobContentId(s_guid, 0x04030201);

private static MethodDefinitionHandle EmitHelloWorld(MetadataBuilder metadata, BlobBuilder ilBuilder)
{
    // Create module and assembly for a console application.
    metadata.AddModule(
        0,
        metadata.GetOrAddString("ConsoleApplication.exe"),
        metadata.GetOrAddGuid(s_guid),
        default(GuidHandle),
        default(GuidHandle));

    metadata.AddAssembly(
        metadata.GetOrAddString("ConsoleApplication"),
        version: new Version(1, 0, 0, 0),
        culture: default(StringHandle),
        publicKey: default(BlobHandle),
        flags: 0,
        hashAlgorithm: AssemblyHashAlgorithm.None);

    // Create references to System.Object and System.Console types.
    AssemblyReferenceHandle mscorlibAssemblyRef = metadata.AddAssemblyReference(
        name: metadata.GetOrAddString("mscorlib"),
        version: new Version(4, 0, 0, 0),
        culture: default(StringHandle),
        publicKeyOrToken: metadata.GetOrAddBlob(
            new byte[] { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 }
            ),
        flags: default(AssemblyFlags),
        hashValue: default(BlobHandle));

    TypeReferenceHandle systemObjectTypeRef = metadata.AddTypeReference(
        mscorlibAssemblyRef,
        metadata.GetOrAddString("System"),
        metadata.GetOrAddString("Object"));

    TypeReferenceHandle systemConsoleTypeRefHandle = metadata.AddTypeReference(
        mscorlibAssemblyRef,
        metadata.GetOrAddString("System"),
        metadata.GetOrAddString("Console"));

    // Get reference to Console.WriteLine(string) method.
    var consoleWriteLineSignature = new BlobBuilder();

    new BlobEncoder(consoleWriteLineSignature).
        MethodSignature().
        Parameters(1,
            returnType => returnType.Void(),
            parameters => parameters.AddParameter().Type().String());

    MemberReferenceHandle consoleWriteLineMemberRef = metadata.AddMemberReference(
        systemConsoleTypeRefHandle,
        metadata.GetOrAddString("WriteLine"),
        metadata.GetOrAddBlob(consoleWriteLineSignature));

    // Get reference to Object's constructor.
    var parameterlessCtorSignature = new BlobBuilder();

    new BlobEncoder(parameterlessCtorSignature).
        MethodSignature(isInstanceMethod: true).
        Parameters(0, returnType => returnType.Void(), parameters => { });

    BlobHandle parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature);

    MemberReferenceHandle objectCtorMemberRef = metadata.AddMemberReference(
        systemObjectTypeRef,
        metadata.GetOrAddString(".ctor"),
        parameterlessCtorBlobIndex);

    // Create signature for "void Main()" method.
    var mainSignature = new BlobBuilder();

    new BlobEncoder(mainSignature).
        MethodSignature().
        Parameters(0, returnType => returnType.Void(), parameters => { });

    var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder);

    var codeBuilder = new BlobBuilder();
    InstructionEncoder il;
    
    // Emit IL for Program::.ctor
    il = new InstructionEncoder(codeBuilder);

    // ldarg.0
    il.LoadArgument(0); 

    // call instance void [mscorlib]System.Object::.ctor()
    il.Call(objectCtorMemberRef);

    // ret
    il.OpCode(ILOpCode.Ret);

    int ctorBodyOffset = methodBodyStream.AddMethodBody(il);
    codeBuilder.Clear();

    // Emit IL for Program::Main
    var flowBuilder = new ControlFlowBuilder();
    il = new InstructionEncoder(codeBuilder, flowBuilder);

    // ldstr "hello"
    il.LoadString(metadata.GetOrAddUserString("Hello, world"));

    // call void [mscorlib]System.Console::WriteLine(string)
    il.Call(consoleWriteLineMemberRef);

    // ret
    il.OpCode(ILOpCode.Ret);

    int mainBodyOffset = methodBodyStream.AddMethodBody(il);
    codeBuilder.Clear();

    // Create method definition for Program::Main
    MethodDefinitionHandle mainMethodDef = metadata.AddMethodDefinition(
        MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
        MethodImplAttributes.IL,
        metadata.GetOrAddString("Main"),
        metadata.GetOrAddBlob(mainSignature),
        mainBodyOffset,
        parameterList: default(ParameterHandle));

    // Create method definition for Program::.ctor
    MethodDefinitionHandle ctorDef = metadata.AddMethodDefinition(
        MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
        MethodImplAttributes.IL,
        metadata.GetOrAddString(".ctor"),
        parameterlessCtorBlobIndex,
        ctorBodyOffset,
        parameterList: default(ParameterHandle));

    // Create type definition for the special <Module> type that holds global functions
    metadata.AddTypeDefinition(
        default(TypeAttributes),
        default(StringHandle),
        metadata.GetOrAddString("<Module>"),
        baseType: default(EntityHandle),
        fieldList: MetadataTokens.FieldDefinitionHandle(1),
        methodList: mainMethodDef);

    // Create type definition for ConsoleApplication.Program
    metadata.AddTypeDefinition(
        TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit,
        metadata.GetOrAddString("ConsoleApplication"),
        metadata.GetOrAddString("Program"),
        baseType: systemObjectTypeRef,
        fieldList: MetadataTokens.FieldDefinitionHandle(1),
        methodList: mainMethodDef);
    
    return mainMethodDef;
}

private static void WritePEImage(
    Stream peStream,
    MetadataBuilder metadataBuilder,
    BlobBuilder ilBuilder,
    MethodDefinitionHandle entryPointHandle
    )
{
    // Create executable with the managed metadata from the specified MetadataBuilder.
    var peHeaderBuilder = new PEHeaderBuilder(
        imageCharacteristics: Characteristics.ExecutableImage
        );

    var peBuilder = new ManagedPEBuilder(
        peHeaderBuilder,
        new MetadataRootBuilder(metadataBuilder),
        ilBuilder,
        entryPoint: entryPointHandle,
        flags: CorFlags.ILOnly,
        deterministicIdProvider: content => s_contentId);

    // Write executable into the specified stream.
    var peBlob = new BlobBuilder();
    BlobContentId contentId = peBuilder.Serialize(peBlob);
    peBlob.WriteContentTo(peStream);
}

public static void BuildHelloWorldApp()
{
    using var peStream = new FileStream(
        "ConsoleApplication.exe", FileMode.OpenOrCreate, FileAccess.ReadWrite
        );
    
    var ilBuilder = new BlobBuilder();
    var metadataBuilder = new MetadataBuilder();

    MethodDefinitionHandle entryPoint = EmitHelloWorld(metadataBuilder, ilBuilder);
    WritePEImage(peStream, metadataBuilder, ilBuilder, entryPoint);
}

Комментарии

Класс MetadataBuilder позволяет создавать сборки программным способом. Эти сборки можно сохранить в файл, в отличие от динамических сборок, созданных классом AssemblyBuilder , который не поддерживает сохранение сборок в файл в .NET 5+ и .NET Core.

API MetadataBuilder использует низкоуровневые конструкции метаданных, такие как таблицы или большие двоичные объекты. Более простой способ динамического создания сборок с помощью C# см. в статье CSharpCompilation Api Roslyn.

Формат метаданных CLI определяется спецификацией ECMA-335. Дополнительные сведения см. в статье Standard ECMA-335 — Common Language Infrastructure (CLI) на веб-сайте Ecma International.

Конструкторы

MetadataBuilder(Int32, Int32, Int32, Int32)

Создает построитель для таблиц и куч метаданных.

Методы

AddAssembly(StringHandle, Version, StringHandle, BlobHandle, AssemblyFlags, AssemblyHashAlgorithm)

Класс MetadataBuilder записывает метаданные для сборки высокопроизводительным способом. Он предназначен для использования компиляторами и другими средствами создания сборок.

AddAssemblyFile(StringHandle, BlobHandle, Boolean)

Класс MetadataBuilder записывает метаданные для сборки высокопроизводительным способом. Он предназначен для использования компиляторами и другими средствами создания сборок.

AddAssemblyReference(StringHandle, Version, StringHandle, BlobHandle, AssemblyFlags, BlobHandle)

Класс MetadataBuilder записывает метаданные для сборки высокопроизводительным способом. Он предназначен для использования компиляторами и другими средствами создания сборок.

AddConstant(EntityHandle, Object)

Добавляет значение по умолчанию для параметра, поля или свойства.

AddCustomAttribute(EntityHandle, EntityHandle, BlobHandle)

Добавляет настраиваемый атрибут.

AddCustomDebugInformation(EntityHandle, GuidHandle, BlobHandle)

Добавляет пользовательскую отладочную информацию.

AddDeclarativeSecurityAttribute(EntityHandle, DeclarativeSecurityAction, BlobHandle)

Добавляет атрибут декларативной безопасности к типу, методу или сборке.

AddDocument(BlobHandle, GuidHandle, BlobHandle, GuidHandle)

Добавляет сведения об отладке документа.

AddEncLogEntry(EntityHandle, EditAndContinueOperation)

Класс MetadataBuilder записывает метаданные для сборки высокопроизводительным способом. Он предназначен для использования компиляторами и другими средствами создания сборок.

AddEncMapEntry(EntityHandle)

Класс MetadataBuilder записывает метаданные для сборки высокопроизводительным способом. Он предназначен для использования компиляторами и другими средствами создания сборок.

AddEvent(EventAttributes, StringHandle, EntityHandle)

Добавляет определение события.

AddEventMap(TypeDefinitionHandle, EventDefinitionHandle)

Класс MetadataBuilder записывает метаданные для сборки высокопроизводительным способом. Он предназначен для использования компиляторами и другими средствами создания сборок.

AddExportedType(TypeAttributes, StringHandle, StringHandle, EntityHandle, Int32)

Добавляет экспортируемый тип.

AddFieldDefinition(FieldAttributes, StringHandle, BlobHandle)

Добавляет определение поля.

AddFieldLayout(FieldDefinitionHandle, Int32)

Определяет макет поля для определения поля.

AddFieldRelativeVirtualAddress(FieldDefinitionHandle, Int32)

Добавляет сопоставление поля с его начальным значением, хранящимся в образе PE.

AddGenericParameter(EntityHandle, GenericParameterAttributes, StringHandle, Int32)

Добавляет определение универсального параметра.

AddGenericParameterConstraint(GenericParameterHandle, EntityHandle)

Добавляет ограничение типа к универсальному параметру.

AddImportScope(ImportScopeHandle, BlobHandle)

Добавляет сведения об отладке локальной области.

AddInterfaceImplementation(TypeDefinitionHandle, EntityHandle)

Добавляет реализацию интерфейса к типу.

AddLocalConstant(StringHandle, BlobHandle)

Добавляет сведения об отладке локальной константы.

AddLocalScope(MethodDefinitionHandle, ImportScopeHandle, LocalVariableHandle, LocalConstantHandle, Int32, Int32)

Добавляет сведения об отладке локальной области.

AddLocalVariable(LocalVariableAttributes, Int32, StringHandle)

Добавляет сведения об отладке локальной переменной.

AddManifestResource(ManifestResourceAttributes, StringHandle, EntityHandle, UInt32)

Добавляет ресурс манифеста.

AddMarshallingDescriptor(EntityHandle, BlobHandle)

Добавляет сведения о маршалинге к полю или параметру.

AddMemberReference(EntityHandle, StringHandle, BlobHandle)

Добавляет строку в таблицу MemberRef.

AddMethodDebugInformation(DocumentHandle, BlobHandle)

Добавляет сведения об отладке метода.

AddMethodDefinition(MethodAttributes, MethodImplAttributes, StringHandle, BlobHandle, Int32, ParameterHandle)

Добавляет определение метода.

AddMethodImplementation(TypeDefinitionHandle, EntityHandle, EntityHandle)

Определяет реализацию объявления метода внутри типа.

AddMethodImport(MethodDefinitionHandle, MethodImportAttributes, StringHandle, ModuleReferenceHandle)

Добавляет сведения об импорте в определение метода.

AddMethodSemantics(EntityHandle, MethodSemanticsAttributes, MethodDefinitionHandle)

Связывает метод (получения, задания, добавления и т. д.) со свойством или событием.

AddMethodSpecification(EntityHandle, BlobHandle)

Добавляет спецификацию метода (для создания экземпляра).

AddModule(Int32, StringHandle, GuidHandle, GuidHandle, GuidHandle)

Класс MetadataBuilder записывает метаданные для сборки высокопроизводительным способом. Он предназначен для использования компиляторами и другими средствами создания сборок.

AddModuleReference(StringHandle)

Класс MetadataBuilder записывает метаданные для сборки высокопроизводительным способом. Он предназначен для использования компиляторами и другими средствами создания сборок.

AddNestedType(TypeDefinitionHandle, TypeDefinitionHandle)

Определяет отношение вложенности к указанным определениям типов.

AddParameter(ParameterAttributes, StringHandle, Int32)

Добавляет определение параметра.

AddProperty(PropertyAttributes, StringHandle, BlobHandle)

Добавляет определение свойства.

AddPropertyMap(TypeDefinitionHandle, PropertyDefinitionHandle)

Класс MetadataBuilder записывает метаданные для сборки высокопроизводительным способом. Он предназначен для использования компиляторами и другими средствами создания сборок.

AddStandaloneSignature(BlobHandle)

Класс MetadataBuilder записывает метаданные для сборки высокопроизводительным способом. Он предназначен для использования компиляторами и другими средствами создания сборок.

AddStateMachineMethod(MethodDefinitionHandle, MethodDefinitionHandle)

Добавляет сведения об отладке метода конечного автомата.

AddTypeDefinition(TypeAttributes, StringHandle, StringHandle, EntityHandle, FieldDefinitionHandle, MethodDefinitionHandle)

Добавляет определение типа.

AddTypeLayout(TypeDefinitionHandle, UInt16, UInt32)

Определяет макет типа для определения типа.

AddTypeReference(EntityHandle, StringHandle, StringHandle)

Добавляет ссылку на тип.

AddTypeSpecification(BlobHandle)

Класс MetadataBuilder записывает метаданные для сборки высокопроизводительным способом. Он предназначен для использования компиляторами и другими средствами создания сборок.

Equals(Object)

Определяет, равен ли указанный объект текущему объекту.

(Унаследовано от Object)
GetHashCode()

Служит хэш-функцией по умолчанию.

(Унаследовано от Object)
GetOrAddBlob(BlobBuilder)

Добавляет указанный большой двоичный объект из неизменяемого массива байтов в кучу больших двоичных объектов, если его еще нет в ней.

GetOrAddBlob(Byte[])

Добавляет указанный большой двоичный объект в кучу больших двоичных объектов, если его еще нет в ней.

GetOrAddBlob(ImmutableArray<Byte>)

Добавляет указанный большой двоичный объект из массива байтов в кучу больших двоичных объектов, если его еще нет в ней.

GetOrAddBlobUTF16(String)

Кодирует строку в кодировке UTF16 в большой двоичный объект, а затем добавляет этот объект в кучу больших двоичных объектов, если его еще нет в ней.

GetOrAddBlobUTF8(String, Boolean)

Кодирует строку в кодировке UTF8 в большой двоичный объект, а затем добавляет этот объект в кучу больших двоичных объектов, если его еще нет в ней.

GetOrAddConstantBlob(Object)

Кодирует значение константы в большой двоичный объект, а затем добавляет этот объект в кучу больших двоичных объектов, если его еще нет в ней. Использует кодировку UTF16 для кодирования строковых констант.

GetOrAddDocumentName(String)

Кодирует имя документа отладки и добавляет его в кучу больших двоичных объектов, если его еще нет в ней.

GetOrAddGuid(Guid)

Добавляет указанный идентификатор GUID в кучу идентификаторов GUID, если его еще нет в ней.

GetOrAddString(String)

Добавляет указанную строку в кучу строк, если ее еще нет в ней.

GetOrAddUserString(String)

Добавляет указанную строку в кучу пользовательских строк, если ее еще нет в ней.

GetRowCount(TableIndex)

Возвращает текущее количество элементов в указанной таблице.

GetRowCounts()

Возвращает текущее количество элементов в каждой таблице.

GetType()

Возвращает объект Type для текущего экземпляра.

(Унаследовано от Object)
MemberwiseClone()

Создает неполную копию текущего объекта Object.

(Унаследовано от Object)
ReserveGuid()

Резервирует место для идентификатора GUID в куче идентификаторов GUID.

ReserveUserString(Int32)

Резервирует место в куче пользовательских строк для строки указанной длины.

SetCapacity(HeapIndex, Int32)

Задает емкость указанной кучи.

SetCapacity(TableIndex, Int32)

Задает емкость указанной таблицы.

ToString()

Возвращает строку, представляющую текущий объект.

(Унаследовано от Object)

Применяется к