Skip to content

Support equivalent of AssemblyBuilder.Save to save in-memory IL to an assembly #62956

Closed
@steveharter

Description

@steveharter

The most common feature request in reflection, with 100+ upvotes, is to add support for equivalent AssemblyBuilder.Save() functionality. Since this exists in .NET Desktop, some consider this an adoption blocker.

Prototyping done in .NET 7.0 to investigate feasibility of adding the Save() via an adapter from AssemblyBuilder to the newer MetadataBuilder which supports writing IL to a Stream\file. Related issues:

System.Reflection.Emit.AssemblyBuilder.Save
Unable to set EntryPoint on generated assemblies with System.Reflection.Emit

We plan to abstract out Reflection.Emit APIs in order to have two implementations, one that having old code to support all downlevel runtime, and a new implementation that replaces the current Reflection.Emit implementation with AssemblyBuilder.Save() support, steps:

  • Abstract out Reflection.Emit APIs, refactor old code that support all downlevel runtime versions.
  • Move the prototyping work into runtime with necessary refactoring
  • Have the new APIs for ParameterBuilder and AssemblyBuilder.Save(string/stream) reviewed and approved
  • Implement the parts that needed for MVP (Minimum Viable Product) AssemblyBuilder.Save(string/stream)
    • Add support for saving different types like struct/class etc. and their references
    • Add support for saving CustomAttributes for all members like assembly/module (PR)
    • Have an APIs proposal for abstracting ILGenerator and other related APIs reviewed and approved.
    • Abstract out ILGenerator accordingly
    • Save interface implementation, nested types for a Type (in PR)
    • Abstract out ParameterBuilder in runtime, add ParameterBuilderImpl and save it to file/stream
    • Add EnumBuilderImpl and save it to file/stream
    • Add support for more complicated signatures for each member (generics/array/byRef/pointer etc)
      • Add GenericTypeParameterBuilderImpl and save a generic Type/Method
    • Save constant value for a Field

Remaining work that out of .NET 8.0:

  • Implement remaining parts needed for AssemblyBuilder.Save(string/stream) (mostly will rely on community contributions)
    • ILGenerator implementation
    • Add support for remaining members
      • Add ConstructorBuilderImpl and save it to file/stream (this needs minimal IL support)
      • Add PropertyBuilderImpl and save it to file/stream (this also needs minimal IL support)
      • Add EventBuildterImpl and save it to file/stream
      • Add implementation for remaining APIs for a MethodBuilder/TypeBuilder/FieldBuilder (like SignatureCallingConvention, *RequiredCustomModifiers, *OptionalCustomModifiers)
    • Have an API for creating PDBs and implement it
    • Entry point support
  • Add support for Running the assembly

Metadata

Metadata

Assignees

Labels

Cost:LWork that requires one engineer up to 4 weeksPriority:2Work that is important, but not critical for the releaseTeam:LibrariesUser StoryA single user-facing feature. Can be grouped under an epic.area-System.Reflection.Emittenet-compatibilityIncompatibility with previous versions or .NET Framework

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions