MetadataBuilder Classe

Definizione

La classe MetadataBuilder scrive metadati per un assembly in modo estremamente efficiente. È progettata per essere usata dai compilatori e da altri strumenti per la generazione di assembly.

public ref class MetadataBuilder sealed
public sealed class MetadataBuilder
type MetadataBuilder = class
Public NotInheritable Class MetadataBuilder
Ereditarietà
MetadataBuilder

Esempio

In questo esempio viene illustrato come generare un assembly dell'applicazione console usando 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);
}

Commenti

La MetadataBuilder classe consente di generare assembly a livello di codice. Questi assembly possono essere salvati in un file, a differenza degli assembly dinamici generati dalla AssemblyBuilder classe , che non supporta il salvataggio di assembly in un file in .NET 5+ e .NET Core.

L'API MetadataBuilder gestisce costrutti di metadati di basso livello, ad esempio tabelle o BLOB. Per un modo più semplice per generare assembly in modo dinamico usando C#, vedere CSharpCompilation in API Roslyn.

Il formato dei metadati dell'interfaccia della riga di comando è definito dalla specifica ECMA-335. Per altre informazioni, vedere Standard ECMA-335 - Common Language Infrastructure (CLI) nel sito Web Ecma International.

Costruttori

MetadataBuilder(Int32, Int32, Int32, Int32)

Crea un generatore per tabelle e heap dei metadati.

Metodi

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

La classe MetadataBuilder scrive metadati per un assembly in modo estremamente efficiente. È progettata per essere usata dai compilatori e da altri strumenti per la generazione di assembly.

AddAssemblyFile(StringHandle, BlobHandle, Boolean)

La classe MetadataBuilder scrive metadati per un assembly in modo estremamente efficiente. È progettata per essere usata dai compilatori e da altri strumenti per la generazione di assembly.

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

La classe MetadataBuilder scrive metadati per un assembly in modo estremamente efficiente. È progettata per essere usata dai compilatori e da altri strumenti per la generazione di assembly.

AddConstant(EntityHandle, Object)

Aggiunge un valore predefinito per un parametro, un campo o una proprietà.

AddCustomAttribute(EntityHandle, EntityHandle, BlobHandle)

Aggiunge un attributo personalizzato.

AddCustomDebugInformation(EntityHandle, GuidHandle, BlobHandle)

Aggiunge informazioni di debug personalizzate.

AddDeclarativeSecurityAttribute(EntityHandle, DeclarativeSecurityAction, BlobHandle)

Aggiunge un attributo di sicurezza dichiarativa a un tipo, un metodo o un assembly.

AddDocument(BlobHandle, GuidHandle, BlobHandle, GuidHandle)

Aggiunge informazioni di debug del documento.

AddEncLogEntry(EntityHandle, EditAndContinueOperation)

La classe MetadataBuilder scrive metadati per un assembly in modo estremamente efficiente. È progettata per essere usata dai compilatori e da altri strumenti per la generazione di assembly.

AddEncMapEntry(EntityHandle)

La classe MetadataBuilder scrive metadati per un assembly in modo estremamente efficiente. È progettata per essere usata dai compilatori e da altri strumenti per la generazione di assembly.

AddEvent(EventAttributes, StringHandle, EntityHandle)

Aggiunge una definizione di evento.

AddEventMap(TypeDefinitionHandle, EventDefinitionHandle)

La classe MetadataBuilder scrive metadati per un assembly in modo estremamente efficiente. È progettata per essere usata dai compilatori e da altri strumenti per la generazione di assembly.

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

Aggiunge un tipo esportato.

AddFieldDefinition(FieldAttributes, StringHandle, BlobHandle)

Aggiunge una definizione di campo.

AddFieldLayout(FieldDefinitionHandle, Int32)

Definisce un layout di campo di una definizione di campo.

AddFieldRelativeVirtualAddress(FieldDefinitionHandle, Int32)

Aggiunge un mapping da un campo al relativo valore iniziale archiviato nell'immagine PE.

AddGenericParameter(EntityHandle, GenericParameterAttributes, StringHandle, Int32)

Aggiunge una definizione di parametro generico.

AddGenericParameterConstraint(GenericParameterHandle, EntityHandle)

Aggiunge un vincolo di tipo a un parametro generico.

AddImportScope(ImportScopeHandle, BlobHandle)

Aggiunge le informazioni di debug dell'ambito locale.

AddInterfaceImplementation(TypeDefinitionHandle, EntityHandle)

Aggiunge una implementazione dell'interfaccia a un tipo.

AddLocalConstant(StringHandle, BlobHandle)

Aggiunge le informazioni di debug della costane locale.

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

Aggiunge le informazioni di debug dell'ambito locale.

AddLocalVariable(LocalVariableAttributes, Int32, StringHandle)

Aggiunge informazioni di debug della variabile locale.

AddManifestResource(ManifestResourceAttributes, StringHandle, EntityHandle, UInt32)

Aggiunge una risorsa del manifesto.

AddMarshallingDescriptor(EntityHandle, BlobHandle)

Aggiunge informazioni di marshalling a un campo o a un parametro.

AddMemberReference(EntityHandle, StringHandle, BlobHandle)

Aggiunge una riga della tabella MemberRef.

AddMethodDebugInformation(DocumentHandle, BlobHandle)

Aggiunge informazioni di debug del metodo.

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

Aggiunge una definizione del metodo.

AddMethodImplementation(TypeDefinitionHandle, EntityHandle, EntityHandle)

Definisce un'implementazione per una dichiarazione di metodo all'interno di un tipo.

AddMethodImport(MethodDefinitionHandle, MethodImportAttributes, StringHandle, ModuleReferenceHandle)

Aggiunge informazioni di importazione a una definizione di metodo.

AddMethodSemantics(EntityHandle, MethodSemanticsAttributes, MethodDefinitionHandle)

Associa un metodo (getter, setter, adder e così via) a una proprietà o un evento.

AddMethodSpecification(EntityHandle, BlobHandle)

Aggiunge una specifica del metodo (creazione di un'istanza).

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

La classe MetadataBuilder scrive metadati per un assembly in modo estremamente efficiente. È progettata per essere usata dai compilatori e da altri strumenti per la generazione di assembly.

AddModuleReference(StringHandle)

La classe MetadataBuilder scrive metadati per un assembly in modo estremamente efficiente. È progettata per essere usata dai compilatori e da altri strumenti per la generazione di assembly.

AddNestedType(TypeDefinitionHandle, TypeDefinitionHandle)

Definisce una relazione di annidamento con le definizioni di tipo specificate.

AddParameter(ParameterAttributes, StringHandle, Int32)

Aggiunge una definizione del parametro.

AddProperty(PropertyAttributes, StringHandle, BlobHandle)

Aggiunge una definizione di proprietà.

AddPropertyMap(TypeDefinitionHandle, PropertyDefinitionHandle)

La classe MetadataBuilder scrive metadati per un assembly in modo estremamente efficiente. È progettata per essere usata dai compilatori e da altri strumenti per la generazione di assembly.

AddStandaloneSignature(BlobHandle)

La classe MetadataBuilder scrive metadati per un assembly in modo estremamente efficiente. È progettata per essere usata dai compilatori e da altri strumenti per la generazione di assembly.

AddStateMachineMethod(MethodDefinitionHandle, MethodDefinitionHandle)

Aggiunge informazioni di debug del metodo della macchina a stati.

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

Aggiunge una definizione di tipo.

AddTypeLayout(TypeDefinitionHandle, UInt16, UInt32)

Definisce un layout di tipo di una definizione di tipo.

AddTypeReference(EntityHandle, StringHandle, StringHandle)

Aggiunge un riferimento al tipo.

AddTypeSpecification(BlobHandle)

La classe MetadataBuilder scrive metadati per un assembly in modo estremamente efficiente. È progettata per essere usata dai compilatori e da altri strumenti per la generazione di assembly.

Equals(Object)

Determina se l'oggetto specificato è uguale all'oggetto corrente.

(Ereditato da Object)
GetHashCode()

Funge da funzione hash predefinita.

(Ereditato da Object)
GetOrAddBlob(BlobBuilder)

Aggiunge il BLOB specificato da una matrice di byte non modificabile all'heap dei BLOB, se non è già presente.

GetOrAddBlob(Byte[])

Aggiunge il BLOB specificato all'heap dei BLOB, se non è già presente.

GetOrAddBlob(ImmutableArray<Byte>)

Aggiunge il BLOB specificato da una matrice di byte all'heap dei BLOB, se non è già presente.

GetOrAddBlobUTF16(String)

Codifica una stringa usando la codifica UTF16 in un BLOB e lo aggiunge all'heap dei BLOB, se non è già presente.

GetOrAddBlobUTF8(String, Boolean)

Codifica una stringa usando la codifica UTF8 in un BLOB e la aggiunge all'heap dei BLOB, se non è già presente.

GetOrAddConstantBlob(Object)

Codifica un valore costante in un BLOB e lo aggiunge all'heap dei BLOB, se non è già presente. Usa UTF16 per codificare le costanti stringa.

GetOrAddDocumentName(String)

Codifica un nome di documento di debug e lo aggiunge all'heap dei BLOB, se non è già presente.

GetOrAddGuid(Guid)

Aggiunge il GUID specificato all'heap dei GUID, se non è già presente.

GetOrAddString(String)

Aggiunge la stringa specificata all'heap delle stringhe, se non è già presente.

GetOrAddUserString(String)

Aggiunge la stringa specificata all'heap delle stringhe utente, se non è già presente.

GetRowCount(TableIndex)

Restituisce il numero corrente di elementi nella tabella specificata.

GetRowCounts()

Restituisce il numero corrente di elementi in ogni tabella.

GetType()

Ottiene l'oggetto Type dell'istanza corrente.

(Ereditato da Object)
MemberwiseClone()

Crea una copia superficiale dell'oggetto Object corrente.

(Ereditato da Object)
ReserveGuid()

Riserva spazio per un GUID nell'heap dei GUID.

ReserveUserString(Int32)

Riserva spazio nell'heap delle stringhe utente per una stringa con la lunghezza specificata.

SetCapacity(HeapIndex, Int32)

Imposta la capacità dell'heap specificato.

SetCapacity(TableIndex, Int32)

Imposta la capacità della tabella specificata.

ToString()

Restituisce una stringa che rappresenta l'oggetto corrente.

(Ereditato da Object)

Si applica a