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

PathAssemblyResolver System.Reflection.MetadataLoadContext should be sealed or allow overrides #36753

Closed
Tracked by #44655
DevDrake opened this issue May 20, 2020 · 8 comments
Labels
api-needs-work API needs work before it is approved, it is NOT ready for implementation area-System.Reflection
Milestone

Comments

@DevDrake
Copy link

DevDrake commented May 20, 2020

_fileToPaths is marked private with seals all possibilities of extending the class over MetadataAssemblyResolver.
If the intention is to seal the class it should be clear, however i dont think it is appropriate. Instead I think the _fileToPaths should be made protected.

Another issue worth considering is making Resolve code to fail/return fast e.g.
if (!_fileToPaths.TryGetValue(assemblyName.Name, out List<string>? paths)) return null; and that should be checked after the Assert.

API Proposal

Make the field protected

public class PathAssemblyResolver : MetadataAssemblyResolver
{
-    private readonly Dictionary<string, List<string>> _fileToPaths;
+    protected readonly Dictionary<string, List<string>> fileToPaths;
}

Alternative Designs

Add a property

public class PathAssemblyResolver : MetadataAssemblyResolver
{
    private readonly Dictionary<string, List<string>> _fileToPaths;
+    protected Dictionary<string, List<string>> FileToPaths => _fileToPaths;
}
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the untriaged New issue has not been triaged by the area owner label May 20, 2020
@Dotnet-GitSync-Bot
Copy link
Collaborator

I couldn't figure out the best area label to add to this issue. Please help me learn by adding exactly one area label.

@DevDrake
Copy link
Author

area-System.Reflection

@DevDrake
Copy link
Author

PR: #36756

@steveharter steveharter added api-needs-work API needs work before it is approved, it is NOT ready for implementation api-suggestion Early API idea and discussion, it is NOT ready for implementation and removed untriaged New issue has not been triaged by the area owner api-needs-work API needs work before it is approved, it is NOT ready for implementation labels Jun 29, 2020
@steveharter
Copy link
Member

Due to 5.0 schedule constraints, this is being moved to Future.

Normally fields are always private or internal, not public or protected, so to address this scenario we may need to add a property.

A workaround is to copy the logic from PathAssemblyResolver into a new class and make necessary changes.

@steveharter steveharter added this to the Future milestone Jul 7, 2020
@steveharter steveharter modified the milestones: Future, 6.0.0 Nov 13, 2020
@krwq krwq modified the milestones: 6.0.0, 7.0.0 Jul 8, 2021
@ghost ghost added the needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration label Jan 10, 2022
@buyaa-n buyaa-n added api-ready-for-review API is ready for review, it is NOT ready for implementation and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration labels Jan 10, 2022
@bartonjs
Copy link
Member

bartonjs commented Jan 11, 2022

Video

For the primary proposal: we (generally) don't expose fields as public or protected.

For the alternative proposal: we feel that simply exposing the field via a property is still too little abstraction and too limiting on the type. Instead, determine what the use cases are for the extensibility and add protected members to provide that functionality without limiting the implementation details (for example, and add method / remove method / indexer)

@bartonjs bartonjs added api-needs-work API needs work before it is approved, it is NOT ready for implementation and removed api-ready-for-review API is ready for review, it is NOT ready for implementation labels Jan 11, 2022
@MarkPflug
Copy link
Contributor

Without knowing the author's exact use-case, I wonder if they could create a "Composite Resolver" that derives from MetadataAssemblyResolver to combine multiple PathAssemblyResolvers. I created such a thing for a tool I was working on, and it worked for my needs.

	sealed class CompositeResolver : MetadataAssemblyResolver
	{
		readonly MetadataAssemblyResolver[] resolvers;
		public CompositeResolver(params MetadataAssemblyResolver[] resolvers)
		{
			this.resolvers = resolvers;
		}

		public override Assembly Resolve(MetadataLoadContext context, AssemblyName assemblyName)
		{
			foreach (var r in this.resolvers)
			{
				var asm = r.Resolve(context, assemblyName);
				if (asm != null)
					return asm;
			}
			return null;
		}
	}
PathAssemblyResolver a, b; // two immutable resolvers
var resolver = new CompositeResolver(a, b);

Sealing PathAssemblyResolver would makes sense if it wasn't a breaking change. Too bad sealed isn't the default in C#.

@steveharter
Copy link
Member

It seems like PathAssemblyResolver should just have been sealed. However, it is too late for that.

I don't yet see a compelling ask for exposing the underlying dictionary for purposes of extending the existing logic. Until we have that, I suggest closing this issue.

@steveharter
Copy link
Member

Closing; please re-open if there is a read-world extensibility need for exposing the underlying dictionary in PathAssemblyResolver.

@ghost ghost locked as resolved and limited conversation to collaborators Feb 20, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-needs-work API needs work before it is approved, it is NOT ready for implementation area-System.Reflection
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

8 participants