Skip to content

Commit 17f2cea

Browse files
Remove MetadataCollection from BoundAttributeDescriptor and other improvements (dotnet#12108)
> [!IMPORTANT] > This change requires an update to the RazorSDK. When Razor flows to `dotnet/dotnet`, dotnet/dotnet@d24637c should be used to update the JSON serialization in the RazorSDK. The loose `string`->`string?` metadata dictionary available on tag helpers is very flexible but adds a lot of overhead. It is somewhat costly to create a `MetadataCollection`, but even more importantly, it's costly to look up keys in a `MetadataCollection`. In general, the compiler stores too much data inefficiently as loose metadata, resulting in larger collections that are more expensive to search. Even worse, the compiler stores what amount to boolean flags in metadata, which negatively impacts performance. This change removes the use of `MetadataCollection` from `BoundAttributeDescriptor` and improves several other properties as well. Here are the highlights: - It turns out that the compiler _always_ adds "PropertyName" metadata when generating a bound attribute. So, that value has been lifted out of metadata and is now stored in `BoundAttributeDescriptor.PropertyName`. - `BoundAttributeDescriptor.TypeName` and `BoundAttributeDescriptor.IndexerTypeName` are now backed by `TypeNameObject`. - More boolean values are stored as `BoundAttributeFlags` rather than as strings in metadata, namely, `IsDirectiveAttribute` and `IsWeaklyTyped`. - I've introduced a new `MetadataObject` abstraction that can be inherited from to create strongly-typed metadata. For `BoundAttributeDescriptor` the compiler can produce three different forms of strongly-typed metadata: 1. `TypeParameterMetadata` - for component type parameters 2. `PropertyMetadata` for component properties 3. `ChildContentParameterMetadata` - component child content parameters. Each `MetadataObject` has custom serialization in JSON and message pack. ---- CI Build: https://dev.azure.com/dnceng/internal/_build/results?buildId=2772130&view=results Test Insertion: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/661893 Toolset Run: https://dev.azure.com/dnceng/internal/_build/results?buildId=2772133&view=results
2 parents 9545488 + f6b2d96 commit 17f2cea

File tree

107 files changed

+112606
-149991
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

107 files changed

+112606
-149991
lines changed

src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorFactoryTest.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ public void CreateDescriptor_UnderstandsStringParameters()
4141
.BoundAttributeDescriptor(attribute =>
4242
attribute
4343
.Name("foo")
44-
.Metadata(PropertyName("foo"))
44+
.PropertyName("foo")
4545
.TypeName(typeof(string).FullName)
4646
.DisplayName("string StringParameterViewComponentTagHelper.foo"))
4747
.BoundAttributeDescriptor(attribute =>
4848
attribute
4949
.Name("bar")
50-
.Metadata(PropertyName("bar"))
50+
.PropertyName("bar")
5151
.TypeName(typeof(string).FullName)
5252
.DisplayName("string StringParameterViewComponentTagHelper.bar"))
5353
.Build();
@@ -84,20 +84,20 @@ public void CreateDescriptor_UnderstandsVariousParameterTypes()
8484
.BoundAttributeDescriptor(attribute =>
8585
attribute
8686
.Name("test-enum")
87-
.Metadata(PropertyName("testEnum"))
87+
.PropertyName("testEnum")
8888
.TypeName(typeof(VariousParameterViewComponent).FullName + "." + nameof(VariousParameterViewComponent.TestEnum))
8989
.AsEnum()
9090
.DisplayName(typeof(VariousParameterViewComponent).FullName + "." + nameof(VariousParameterViewComponent.TestEnum) + " VariousParameterViewComponentTagHelper.testEnum"))
9191
.BoundAttributeDescriptor(attribute =>
9292
attribute
9393
.Name("test-string")
94-
.Metadata(PropertyName("testString"))
94+
.PropertyName("testString")
9595
.TypeName(typeof(string).FullName)
9696
.DisplayName("string VariousParameterViewComponentTagHelper.testString"))
9797
.BoundAttributeDescriptor(attribute =>
9898
attribute
9999
.Name("baz")
100-
.Metadata(PropertyName("baz"))
100+
.PropertyName("baz")
101101
.TypeName(typeof(int).FullName)
102102
.DisplayName("int VariousParameterViewComponentTagHelper.baz"))
103103
.Build();
@@ -132,13 +132,13 @@ public void CreateDescriptor_UnderstandsGenericParameters()
132132
.BoundAttributeDescriptor(attribute =>
133133
attribute
134134
.Name("foo")
135-
.Metadata(PropertyName("Foo"))
135+
.PropertyName("Foo")
136136
.TypeName("System.Collections.Generic.List<System.String>")
137137
.DisplayName("System.Collections.Generic.List<System.String> GenericParameterViewComponentTagHelper.Foo"))
138138
.BoundAttributeDescriptor(attribute =>
139139
attribute
140140
.Name("bar")
141-
.Metadata(PropertyName("Bar"))
141+
.PropertyName("Bar")
142142
.TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
143143
.AsDictionaryAttribute("bar-", typeof(int).FullName)
144144
.DisplayName("System.Collections.Generic.Dictionary<System.String, System.Int32> GenericParameterViewComponentTagHelper.Bar"))

src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorProviderTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@ public class StringParameterViewComponent
5050
.BoundAttributeDescriptor(attribute =>
5151
attribute
5252
.Name("foo")
53-
.Metadata(PropertyName("foo"))
53+
.PropertyName("foo")
5454
.TypeName(typeof(string).FullName)
5555
.DisplayName("string StringParameterViewComponentTagHelper.foo"))
5656
.BoundAttributeDescriptor(attribute =>
5757
attribute
5858
.Name("bar")
59-
.Metadata(PropertyName("bar"))
59+
.PropertyName("bar")
6060
.TypeName(typeof(string).FullName)
6161
.DisplayName("string StringParameterViewComponentTagHelper.bar"))
6262
.Build();

src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperPassTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper()
7272
.BoundAttributeDescriptor(attribute => attribute
7373
.Name("Foo")
7474
.TypeName("System.Int32")
75-
.Metadata(PropertyName("Foo")))
75+
.PropertyName("Foo"))
7676
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud"))
7777
.Build();
7878

@@ -109,7 +109,7 @@ public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper_Wit
109109
.BoundAttributeDescriptor(attribute => attribute
110110
.Name("Foo")
111111
.TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
112-
.Metadata(PropertyName("Tags"))
112+
.PropertyName("Tags")
113113
.AsDictionaryAttribute("foo-", "System.Int32"))
114114
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud"))
115115
.Build();
@@ -143,7 +143,7 @@ public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper_Nes
143143
var tagHelper1 = TagHelperDescriptorBuilder.Create("PTestTagHelper", "TestAssembly")
144144
.Metadata(TypeName("PTestTagHelper"))
145145
.BoundAttributeDescriptor(attribute => attribute
146-
.Metadata(PropertyName("Foo"))
146+
.PropertyName("Foo")
147147
.Name("Foo")
148148
.TypeName("System.Int32"))
149149
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
@@ -154,7 +154,7 @@ public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper_Nes
154154
TypeName("__Generated__TagCloudViewComponentTagHelper"),
155155
new(ViewComponentTagHelperMetadata.Name, "TagCloud"))
156156
.BoundAttributeDescriptor(attribute => attribute
157-
.Metadata(PropertyName("Foo"))
157+
.PropertyName("Foo")
158158
.Name("Foo")
159159
.TypeName("System.Int32"))
160160
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud"))

src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperTargetExtensionTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public void WriteViewComponentTagHelper_GeneratesViewComponentTagHelper()
2424
.BoundAttributeDescriptor(attribute => attribute
2525
.Name("Foo")
2626
.TypeName("System.Int32")
27-
.Metadata(PropertyName("Foo")))
27+
.PropertyName("Foo"))
2828
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud"))
2929
.Build();
3030

@@ -78,7 +78,7 @@ public void WriteViewComponentTagHelper_GeneratesViewComponentTagHelper_WithInde
7878
.BoundAttributeDescriptor(attribute => attribute
7979
.Name("Foo")
8080
.TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
81-
.Metadata(PropertyName("Tags"))
81+
.PropertyName("Tags")
8282
.AsDictionaryAttribute("foo-", "System.Int32"))
8383
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud"))
8484
.Build();

src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/IntegrationTests/InstrumentationPassIntegrationTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ public void BasicTest()
5050
{
5151
builder => builder
5252
.Name("value")
53-
.Metadata(PropertyName("FooProp"))
53+
.PropertyName("FooProp")
5454
.TypeName("System.String"), // Gets preallocated
5555
builder => builder
5656
.Name("date")
57-
.Metadata(PropertyName("BarProp"))
57+
.PropertyName("BarProp")
5858
.TypeName("System.DateTime"), // Doesn't get preallocated
5959
})
6060
};

src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorFactoryTest.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ public void CreateDescriptor_UnderstandsStringParameters()
4141
.BoundAttributeDescriptor(attribute =>
4242
attribute
4343
.Name("foo")
44-
.Metadata(PropertyName("foo"))
44+
.PropertyName("foo")
4545
.TypeName(typeof(string).FullName)
4646
.DisplayName("string StringParameterViewComponentTagHelper.foo"))
4747
.BoundAttributeDescriptor(attribute =>
4848
attribute
4949
.Name("bar")
50-
.Metadata(PropertyName("bar"))
50+
.PropertyName("bar")
5151
.TypeName(typeof(string).FullName)
5252
.DisplayName("string StringParameterViewComponentTagHelper.bar"))
5353
.Build();
@@ -84,20 +84,20 @@ public void CreateDescriptor_UnderstandsVariousParameterTypes()
8484
.BoundAttributeDescriptor(attribute =>
8585
attribute
8686
.Name("test-enum")
87-
.Metadata(PropertyName("testEnum"))
87+
.PropertyName("testEnum")
8888
.TypeName(typeof(VariousParameterViewComponent).FullName + "." + nameof(VariousParameterViewComponent.TestEnum))
8989
.AsEnum()
9090
.DisplayName(typeof(VariousParameterViewComponent).FullName + "." + nameof(VariousParameterViewComponent.TestEnum) + " VariousParameterViewComponentTagHelper.testEnum"))
9191
.BoundAttributeDescriptor(attribute =>
9292
attribute
9393
.Name("test-string")
94-
.Metadata(PropertyName("testString"))
94+
.PropertyName("testString")
9595
.TypeName(typeof(string).FullName)
9696
.DisplayName("string VariousParameterViewComponentTagHelper.testString"))
9797
.BoundAttributeDescriptor(attribute =>
9898
attribute
9999
.Name("baz")
100-
.Metadata(PropertyName("baz"))
100+
.PropertyName("baz")
101101
.TypeName(typeof(int).FullName)
102102
.DisplayName("int VariousParameterViewComponentTagHelper.baz"))
103103
.Build();
@@ -132,13 +132,13 @@ public void CreateDescriptor_UnderstandsGenericParameters()
132132
.BoundAttributeDescriptor(attribute =>
133133
attribute
134134
.Name("foo")
135-
.Metadata(PropertyName("Foo"))
135+
.PropertyName("Foo")
136136
.TypeName("System.Collections.Generic.List<System.String>")
137137
.DisplayName("System.Collections.Generic.List<System.String> GenericParameterViewComponentTagHelper.Foo"))
138138
.BoundAttributeDescriptor(attribute =>
139139
attribute
140140
.Name("bar")
141-
.Metadata(PropertyName("Bar"))
141+
.PropertyName("Bar")
142142
.TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
143143
.AsDictionaryAttribute("bar-", typeof(int).FullName)
144144
.DisplayName("System.Collections.Generic.Dictionary<System.String, System.Int32> GenericParameterViewComponentTagHelper.Bar"))
@@ -174,13 +174,13 @@ public void CreateDescriptor_ForSyncViewComponentWithInvokeInBaseType_Works()
174174
.BoundAttributeDescriptor(attribute =>
175175
attribute
176176
.Name("foo")
177-
.Metadata(PropertyName("foo"))
177+
.PropertyName("foo")
178178
.TypeName(typeof(string).FullName)
179179
.DisplayName("string SyncDerivedViewComponentTagHelper.foo"))
180180
.BoundAttributeDescriptor(attribute =>
181181
attribute
182182
.Name("bar")
183-
.Metadata(PropertyName("bar"))
183+
.PropertyName("bar")
184184
.TypeName(typeof(string).FullName)
185185
.DisplayName("string SyncDerivedViewComponentTagHelper.bar"))
186186
.Build();

src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorProviderTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@ public class StringParameterViewComponent
5050
.BoundAttributeDescriptor(attribute =>
5151
attribute
5252
.Name("foo")
53-
.Metadata(PropertyName("foo"))
53+
.PropertyName("foo")
5454
.TypeName(typeof(string).FullName)
5555
.DisplayName("string StringParameterViewComponentTagHelper.foo"))
5656
.BoundAttributeDescriptor(attribute =>
5757
attribute
5858
.Name("bar")
59-
.Metadata(PropertyName("bar"))
59+
.PropertyName("bar")
6060
.TypeName(typeof(string).FullName)
6161
.DisplayName("string StringParameterViewComponentTagHelper.bar"))
6262
.Build();

src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperPassTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper()
7272
.BoundAttributeDescriptor(attribute => attribute
7373
.Name("Foo")
7474
.TypeName("System.Int32")
75-
.Metadata(PropertyName("Foo")))
75+
.PropertyName("Foo"))
7676
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud"))
7777
.Build();
7878

@@ -111,7 +111,7 @@ public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper_Wit
111111
.BoundAttributeDescriptor(attribute => attribute
112112
.Name("Foo")
113113
.TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
114-
.Metadata(PropertyName("Tags"))
114+
.PropertyName("Tags")
115115
.AsDictionaryAttribute("foo-", "System.Int32"))
116116
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud"))
117117
.Build();
@@ -147,7 +147,7 @@ public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper_Nes
147147
var tagHelper1 = TagHelperDescriptorBuilder.Create("PTestTagHelper", "TestAssembly")
148148
.Metadata(TypeName("PTestTagHelper"))
149149
.BoundAttributeDescriptor(attribute => attribute
150-
.Metadata(PropertyName("Foo"))
150+
.PropertyName("Foo")
151151
.Name("Foo")
152152
.TypeName("System.Int32"))
153153
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
@@ -158,7 +158,7 @@ public void ViewComponentTagHelperPass_Execute_CreatesViewComponentTagHelper_Nes
158158
TypeName("__Generated__TagCloudViewComponentTagHelper"),
159159
new(ViewComponentTagHelperMetadata.Name, "TagCloud"))
160160
.BoundAttributeDescriptor(attribute => attribute
161-
.Metadata(PropertyName("Foo"))
161+
.PropertyName("Foo")
162162
.Name("Foo")
163163
.TypeName("System.Int32"))
164164
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud"))

src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperTargetExtensionTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public void WriteViewComponentTagHelper_GeneratesViewComponentTagHelper()
2424
.BoundAttributeDescriptor(attribute => attribute
2525
.Name("Foo")
2626
.TypeName("System.Int32")
27-
.Metadata(PropertyName("Foo")))
27+
.PropertyName("Foo"))
2828
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud"))
2929
.Build();
3030

@@ -78,7 +78,7 @@ public void WriteViewComponentTagHelper_GeneratesViewComponentTagHelper_WithInde
7878
.BoundAttributeDescriptor(attribute => attribute
7979
.Name("Foo")
8080
.TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
81-
.Metadata(PropertyName("Tags"))
81+
.PropertyName("Tags")
8282
.AsDictionaryAttribute("foo-", "System.Int32"))
8383
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud"))
8484
.Build();

src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorFactoryTest.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ public void CreateDescriptor_UnderstandsStringParameters()
3939
.BoundAttributeDescriptor(attribute =>
4040
attribute
4141
.Name("foo")
42-
.Metadata(PropertyName("foo"))
42+
.PropertyName("foo")
4343
.TypeName(typeof(string).FullName)
4444
.DisplayName("string StringParameterViewComponentTagHelper.foo"))
4545
.BoundAttributeDescriptor(attribute =>
4646
attribute
4747
.Name("bar")
48-
.Metadata(PropertyName("bar"))
48+
.PropertyName("bar")
4949
.TypeName(typeof(string).FullName)
5050
.DisplayName("string StringParameterViewComponentTagHelper.bar"))
5151
.Build();
@@ -81,20 +81,20 @@ public void CreateDescriptor_UnderstandsVariousParameterTypes()
8181
.BoundAttributeDescriptor(attribute =>
8282
attribute
8383
.Name("test-enum")
84-
.Metadata(PropertyName("testEnum"))
84+
.PropertyName("testEnum")
8585
.TypeName("TestNamespace.VariousParameterViewComponent.TestEnum")
8686
.AsEnum()
8787
.DisplayName("TestNamespace.VariousParameterViewComponent.TestEnum VariousParameterViewComponentTagHelper.testEnum"))
8888
.BoundAttributeDescriptor(attribute =>
8989
attribute
9090
.Name("test-string")
91-
.Metadata(PropertyName("testString"))
91+
.PropertyName("testString")
9292
.TypeName(typeof(string).FullName)
9393
.DisplayName("string VariousParameterViewComponentTagHelper.testString"))
9494
.BoundAttributeDescriptor(attribute =>
9595
attribute
9696
.Name("baz")
97-
.Metadata(PropertyName("baz"))
97+
.PropertyName("baz")
9898
.TypeName(typeof(int).FullName)
9999
.DisplayName("int VariousParameterViewComponentTagHelper.baz"))
100100
.Build();
@@ -129,13 +129,13 @@ public void CreateDescriptor_UnderstandsGenericParameters()
129129
.BoundAttributeDescriptor(attribute =>
130130
attribute
131131
.Name("foo")
132-
.Metadata(PropertyName("Foo"))
132+
.PropertyName("Foo")
133133
.TypeName("System.Collections.Generic.List<System.String>")
134134
.DisplayName("System.Collections.Generic.List<System.String> GenericParameterViewComponentTagHelper.Foo"))
135135
.BoundAttributeDescriptor(attribute =>
136136
attribute
137137
.Name("bar")
138-
.Metadata(PropertyName("Bar"))
138+
.PropertyName("Bar")
139139
.TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
140140
.AsDictionaryAttribute("bar-", typeof(int).FullName)
141141
.DisplayName("System.Collections.Generic.Dictionary<System.String, System.Int32> GenericParameterViewComponentTagHelper.Bar"))
@@ -171,13 +171,13 @@ public void CreateDescriptor_ForSyncViewComponentWithInvokeInBaseType_Works()
171171
.BoundAttributeDescriptor(attribute =>
172172
attribute
173173
.Name("foo")
174-
.Metadata(PropertyName("foo"))
174+
.PropertyName("foo")
175175
.TypeName(typeof(string).FullName)
176176
.DisplayName("string SyncDerivedViewComponentTagHelper.foo"))
177177
.BoundAttributeDescriptor(attribute =>
178178
attribute
179179
.Name("bar")
180-
.Metadata(PropertyName("bar"))
180+
.PropertyName("bar")
181181
.TypeName(typeof(string).FullName)
182182
.DisplayName("string SyncDerivedViewComponentTagHelper.bar"))
183183
.Build();

0 commit comments

Comments
 (0)