Add AssemblyLoadContext.SetAssemblyLocationOverride#129773
Conversation
Adds a static, set-once callback that overrides the value returned by Assembly.Location. The callback is stored in the shared AssemblyLoadContext and applied by RuntimeAssembly.Location on CoreCLR, Mono, and NativeAOT. Updates the System.Runtime.Loader reference assembly and adds tests covering the override, the set-once guard, and null handling. Fix dotnet#127097
|
@cdmazom please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.
Contributor License AgreementContribution License AgreementThis Contribution License Agreement ( “Agreement” ) is agreed to by the party signing below ( “You” ), 1. Definitions. “Code” means the computer software code, whether in human-readable or machine-executable form, “Project” means any of the projects owned or managed by .NET Foundation and offered under a license “Submit” is the act of uploading, submitting, transmitting, or distributing code or other content to any “Submission” means the Code and any other copyrightable material Submitted by You, including any 2. Your Submission. You must agree to the terms of this Agreement before making a Submission to any 3. Originality of Work. You represent that each of Your Submissions is entirely Your 4. Your Employer. References to “employer” in this Agreement include Your employer or anyone else 5. Licenses. a. Copyright License. You grant .NET Foundation, and those who receive the Submission directly b. Patent License. You grant .NET Foundation, and those who receive the Submission directly or c. Other Rights Reserved. Each party reserves all rights not expressly granted in this Agreement. 6. Representations and Warranties. You represent that You are legally entitled to grant the above 7. Notice to .NET Foundation. You agree to notify .NET Foundation in writing of any facts or 8. Information about Submissions. You agree that contributions to Projects and information about 9. Governing Law/Jurisdiction. This Agreement is governed by the laws of the State of Washington, and 10. Entire Agreement/Assignment. This Agreement is the entire agreement between the parties, and .NET Foundation dedicates this Contribution License Agreement to the public domain according to the Creative Commons CC0 1. |
|
Tagging subscribers to this area: @steveisok, @dotnet/area-system-reflection |
There was a problem hiding this comment.
Pull request overview
This PR introduces a new public API, AssemblyLoadContext.SetAssemblyLocationOverride, which allows a process-wide, set-once callback to override the value returned by Assembly.Location. The override is applied consistently across CoreCLR, Mono, and NativeAOT by routing each runtime’s RuntimeAssembly.Location implementation through a shared resolver in AssemblyLoadContext.
Changes:
- Adds
AssemblyLoadContext.SetAssemblyLocationOverride(Func<Assembly, string, string>)and an internalResolveAssemblyLocationhelper inSystem.Private.CoreLib. - Updates CoreCLR/Mono/NativeAOT
Assembly.Locationimplementations to apply the override. - Updates the System.Runtime.Loader reference assembly and adds tests for null argument, override behavior, and set-once enforcement.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs | Adds the set-once callback storage, public setter API, and internal location resolver used by all runtimes. |
| src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs | Applies the location override when returning Assembly.Location on CoreCLR. |
| src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs | Applies the location override when returning Assembly.Location on Mono. |
| src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ThunkedApis.cs | Applies the location override when returning Assembly.Location on NativeAOT. |
| src/libraries/System.Runtime.Loader/ref/System.Runtime.Loader.cs | Adds the new public API to the reference assembly surface. |
| src/libraries/System.Runtime.Loader/tests/AssemblyLoadContextTest.cs | Adds tests for null argument, stream-loaded override behavior, and set-once guard (RemoteExecutor isolation). |
| src/libraries/System.Private.CoreLib/src/Resources/Strings.resx | Adds SR string for the “already set” exception message. |
Co-authored-by: Theodore Tsirpanis <teo@tsirpanis.gr>
|
Could you please sign the Contributor License Agreement? This is good to go otherwise. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| string asmPath = ExtractEmbeddedAssembly("System.Runtime.Loader.Tests.AssemblyVersion1"); | ||
| try | ||
| { | ||
| // Loading from a stream means the runtime has no location, so the override kicks in. | ||
| var streamAlc = new AssemblyLoadContext("LocationOverride_Stream", isCollectible: true); | ||
| Assembly streamLoaded; | ||
| using (FileStream fs = File.OpenRead(asmPath)) | ||
| { | ||
| streamLoaded = streamAlc.LoadFromStream(fs); | ||
| } | ||
| Assert.Equal($"/overridden/{streamLoaded.GetName().Name}.dll", streamLoaded.Location); | ||
|
|
||
| // The same assembly loaded from a path (into a separate context) has a real location, | ||
| // so the callback leaves it untouched. | ||
| var pathAlc = new AssemblyLoadContext("LocationOverride_Path", isCollectible: true); | ||
| Assembly fileLoaded = pathAlc.LoadFromAssemblyPath(asmPath); | ||
| Assert.False(string.IsNullOrEmpty(fileLoaded.Location)); | ||
| Assert.DoesNotContain("/overridden/", fileLoaded.Location); | ||
| } | ||
| finally | ||
| { | ||
| try { File.Delete(asmPath); } catch { } | ||
| } |
Adds a static, set-once callback that overrides the value returned by Assembly.Location. The callback is stored in the shared AssemblyLoadContext and applied by RuntimeAssembly.Location on CoreCLR, Mono, and NativeAOT.
Updates the System.Runtime.Loader reference assembly and adds tests covering the override, the set-once guard, and null handling.
Fix #127097