Skip to content

Conversation

@DustinCampbell
Copy link
Member

This change provides an alternative API to add metadata to tag helper builder objects. The existing API allows key/value pairs to be added to an IDictionary<string, string?>, which is then converted to a MetadataCollection. The new API simply takes a MetadataCollection directly, which allows common instances to be shared across tag helpers.

A couple of notes:

  1. I've had to make a few APIs public so that they can be called from the "MVC Extensions" projects. However, the expectation is that these aren't really a problem since they won't ever be shipped on NuGet.
  2. There are loads of test changes here to avoid calling the existing metadata API on builders.

@DustinCampbell DustinCampbell requested review from a team as code owners May 31, 2023 22:29
Copy link
Member

@davidwengier davidwengier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me, and tooling side looks good.

Would be interesting to see how many PropertyName metadata items share the same names, in a real app. I suspect there would be a lot of common attribute descriptors (Value, Items, Title etc.), it might be worth using a dictionary to share KVP instances.

@DustinCampbell
Copy link
Member Author

it might be worth using a dictionary to share KVP instances.

It might be useful to intern the strings, but KVPs are structs, so they can't exactly be shared. FWIW, the biggest offenders were the many RequiredAttributeDescriptors with identical "IsDirectiveAttribute" metadata.

Copy link
Member

@chsienki chsienki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. @333fred Have we decided if we're doing API review for Razor too?

@DustinCampbell
Copy link
Member Author

LGTM. @333fred Have we decided if we're doing API review for Razor too?

I don't want to put words in his mouth, but @333fred and I chatted about this the other day, and I believe the conclusion was that we have to review the whole thing eventually. However, we don't need to do that yet. He'll correct me if I got that wrong.

FWIW, I made these public to avoid having to add InternalsVisibleTo for the MVC Extensions projects, which I think we don't want.

Copy link
Member

@jaredpar jaredpar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got most of the way through the change. Reviewed the core implementation changes and probably half the test cases. Had a few Qs. Will pick up rest of the review later today

internal static class TagHelperBoundAttributeDescriptorExtensions
{
private static bool IsTrue(this BoundAttributeDescriptor attribute, string key)
=> attribute.Metadata.TryGetValue(key, out var value) && value == bool.TrueString;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR effectively repeats a number of helpers between BoundAttributeDescriptor and BoundAttributeDescriptorBuilder. Did you consider using an interface for these common methods so we could have a single IsTrue, SetMetadata, etc ... methods?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't consider that, no. There are loads of these helper extension methods (mostly public) all over the place, so I decided to just follow that pattern. When we can finally change the public surface area of tag helper descriptors, I want to revisit all of this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, providing an interface wouldn't give us a single copy of the methods. We would have to copy the implementations to each builder type because there's no hierarchy relationship between them.

@333fred
Copy link
Member

333fred commented Jun 2, 2023

Nope, you're right. I do owe you a review on this that I've started, and will try to get through the rest of today.

Copy link
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finished review of the compiler layer. Overall looking good, just a few minor questions.

@DustinCampbell DustinCampbell merged commit 762c615 into dotnet:main Jun 7, 2023
@DustinCampbell DustinCampbell deleted the dedupe-metadata branch June 7, 2023 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants