Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API Proposal]: Add support for skipping visibility checks with AssemblyBuilder.DefineDynamicAssembly #85020

Closed
MichalPetryka opened this issue Apr 18, 2023 · 2 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Reflection.Emit

Comments

@MichalPetryka
Copy link
Contributor

MichalPetryka commented Apr 18, 2023

Background and motivation

DynamicMethod allows accessing non public elements with its restrictedSkipVisibility constructor parameter, but using AssemblyBuilder and emitting complete types this way does not provide such functionality.
Accessing such elements can be useful when working with runtime generation for example in serialization scenarios.
There exists a non documented IgnoreAccessChecksToAttribute attribute today, runtime users can't however rely on it being always supported due to being undocumented.

API Proposal

namespace System.Reflection.Emit;

public class AssemblyBuilder
{
    public static System.Reflection.Emit.AssemblyBuilder DefineDynamicAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access, bool restrictedSkipVisibility);
    public static System.Reflection.Emit.AssemblyBuilder DefineDynamicAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access, System.Collections.Generic.IEnumerable<System.Reflection.Emit.CustomAttributeBuilder>? assemblyAttributes, bool restrictedSkipVisibility);
}

API Usage

AssemblyName aName = new AssemblyName("DynamicAssemblyExample");
AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run, true);
// emit module and types
TypeBuilder tb = ...
ConstructorInfo ctorOfSomeNonPublicTypeImplementingISomeInterface = ...

MethodBuilder meth = tb.DefineMethod(
            "MyMethod",
            MethodAttributes.Public,
            typeof(ISomeInterface),
            new Type[] {  });

ILGenerator methIL = meth.GetILGenerator();
methIL.Emit(OpCodes.Newobj, ctorOfSomeNonPublicTypeImplementingISomeInterface);
methIL.Emit(OpCodes.Ret);

Alternative Designs

Document and expose the hidden IgnoreAccessChecksToAttribute.

Risks

Accessing members that shouldn't be accessed, already possible with DynamicMethod though.

@MichalPetryka MichalPetryka added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Apr 18, 2023
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Apr 18, 2023
@ghost
Copy link

ghost commented Apr 18, 2023

Tagging subscribers to this area: @dotnet/area-system-reflection-emit
See info in area-owners.md if you want to be subscribed.

Issue Details

Background and motivation

DynamicMethod allows accessing non public elements with its restrictedSkipVisibility constructor parameter, but using AssemblyBuilder and emitting complete types this way does not provide such functionality.
Accessing such elements can be useful when working with runtime generation for example in serialization scenarios.
There exists a non documented IgnoreAccessChecksToAttribute attribute today, runtime users can't however rely on it being always supported due to being undocumented.

API Proposal

namespace System.Reflection.Emit;

public class AssemblyBuilder
{
    public static System.Reflection.Emit.AssemblyBuilder DefineDynamicAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access, bool restrictedSkipVisibility);
public static System.Reflection.Emit.AssemblyBuilder DefineDynamicAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access, System.Collections.Generic.IEnumerable<System.Reflection.Emit.CustomAttributeBuilder>? assemblyAttributes, bool restrictedSkipVisibility);
}

API Usage

AssemblyName aName = new AssemblyName("DynamicAssemblyExample");
AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run, true);
// emit module and types
ConstructorInfo ctorOfSomeNonPublicTypeImplementingISomeInterface = ...

MethodBuilder meth = tb.DefineMethod(
            "MyMethod",
            MethodAttributes.Public,
            typeof(ISomeInterface),
            new Type[] {  });

ILGenerator methIL = meth.GetILGenerator();
methIL.Emit(OpCodes.Newobj, ctorOfSomeNonPublicTypeImplementingISomeInterface);
methIL.Emit(OpCodes.Ret);

Alternative Designs

Document and expose the hidden IgnoreAccessChecksToAttribute.

Risks

Accessing members that shouldn't be accessed, already possible with DynamicMethod though.

Author: MichalPetryka
Assignees: -
Labels:

api-suggestion, area-System.Reflection.Emit

Milestone: -

@steveharter
Copy link
Member

steveharter commented May 23, 2023

Since the compiler does not want to support this, this scenario is not supported by design.

Closing this issue in favor of #81741.

See also #37875

Currently the general supported mechanisms:

  • Generating IL to call the method
  • Use reflection (which has been made much faster in 7.0)

@ghost ghost removed the untriaged New issue has not been triaged by the area owner label May 23, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Jul 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Reflection.Emit
Projects
None yet
Development

No branches or pull requests

2 participants