Closed teo-tsirpanis closed 1 year ago
Tagging subscribers to this area: @dotnet/area-system-reflection-emit See info in area-owners.md if you want to be subscribed.
Author: | teo-tsirpanis |
---|---|
Assignees: | - |
Labels: | `api-suggestion`, `area-System.Reflection.Emit` |
Milestone: | - |
public ModuleBuilder? GetDynamicModule(string name)
could also obsoleted as its could only return the
_manifestModuleBuilder
when ManifestModuleName
is passed
https://github.com/dotnet/runtime/blob/25f2fb5bcdffc9108059a2da7f3ad25b4b48b064/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs#L285-L296
Thanks @buyaa-n, I didn't notice GetModuleBuilder
, I edited the proposal. In fact that API is broken; it will only return the manifest module when the name parameter is equal to "RefEmit_InMemoryManifestModule"
, which no one could guess.
Perhaps we will want to separate the API proposal from the obsoletion, mainly because the decision for marking the other API as obsolete might not make sense if we ever want to support AssemblyBuilder.Save
. cc @jkotas
The current .NET Core behavior looks like a bug that got introduced with stripping support for multimodule assemblies. If you run this:
var ab = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Test"), AssemblyBuilderAccess.Run);
var mb = ab.DefineDynamicModule("foo");
Console.WriteLine(mb);
It is going to print "foo" on .NET Framework and RefEmit_InMemoryManifestModule
on .NET Core.
Would it make more sense to fix DefineDynamicModule
to respect the provided module name just like .NET Framework did instead of hardcoding an arbitrary one?
To streamline the Reflection.Emit API and remove the concept of the one-to-many relation between assemblies and modules from the codebases and the things new developers have to learn
If we want to start obsoleting methods related to multi-module support, we should start with System.Reflection that is much more prevalent than System.Reflection.Emit.
Closing as per the @jkotas's comment above
Background and motivation
With multi-module assemblies not supported in modern .NET, the
AssemblyBuilder.DefineDynamicModule
has lost its reason of existence, and is a source of confusion over the module name it accepts as a parameter and whether it actually matters, while in fact is does not influence the dynamic assembly at all.To further prove that the API is meaningless, try running the following:
It will print
<In Memory Module>
.To streamline the Reflection.Emit API and remove the concept of the one-to-many relation between assemblies and modules from the codebases and the things new developers have to learn, I propose to obsolete
AssemblyBuilder.DefineDynamicModule
(edit: andGetDynamicModule
) and add a new property that returns the one and onlyModuleBuilder
of anAssemblyBuilder
, without needing to explicitly give it a name.API Proposal
This property will return the dynamic assembly's module. It can be accessed multiple times.
DefineDynamicModule
will still check that thename
parameter is valid and that it has been called only once, but it will always returnManifestModuleBuilder
, without having any other effect.If this API gets approved I can implement it.
API Usage
Alternative Designs
ModuleBuilder
(akin toFileStream.SafeFileHandle
property that has the same name as its type), orMainModuleBuilder
. The name I proposed matches the existingManifestModule
property and there is little chance for the property to be overlooked; the obsoletion message will guide developers to it.ModuleBuilder
'sDefine***
methods toAsemblyBuilder
. That was my initial thought, but still an assembly and a module are distinct things (attributes can be applied to either of them for example), and it would make existing code slightly harder to migrate, or even present challenges for a library that multi-targets. My proposal is much easier to migrate to.Risks
Reflection.Emit
APIs are mature enough to not warrant an essentially cosmetic change.AssemblyBuilder.Save
gets implemented.