diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Host/ModelExpressionPass.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Host/ModelExpressionPass.cs
index 7a5962268f..9de73fbb4a 100644
--- a/src/Microsoft.AspNetCore.Mvc.Razor.Host/ModelExpressionPass.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Razor.Host/ModelExpressionPass.cs
@@ -10,6 +10,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
{
public class ModelExpressionPass : RazorIRPassBase, IRazorIROptimizationPass
{
+ private const string ModelExpressionTypeName = "Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression";
+
public override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIRNode irDocument)
{
var visitor = new Visitor();
@@ -22,7 +24,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
public override void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
{
- if (string.Equals(node.Descriptor.TypeName, "Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression", StringComparison.Ordinal))
+ if (string.Equals(node.Descriptor.TypeName, ModelExpressionTypeName, StringComparison.Ordinal) ||
+ (node.IsIndexerNameMatch &&
+ string.Equals(node.Descriptor.IndexerTypeName, ModelExpressionTypeName, StringComparison.Ordinal)))
{
var expression = new CSharpExpressionIRNode();
var builder = RazorIRBuilder.Create(expression);
diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperDescriptorConventions.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperDescriptorConventions.cs
index 5e7c24ccf7..c35195bf59 100644
--- a/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperDescriptorConventions.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperDescriptorConventions.cs
@@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
public static class ViewComponentTagHelperDescriptorConventions
{
///
- /// The key in a containing
+ /// The key in a containing
/// the short name of a view component.
///
public static readonly string ViewComponentNameKey = "ViewComponentName";
@@ -22,6 +22,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
/// The to check.
/// Whether a represents a view component.
public static bool IsViewComponentDescriptor(TagHelperDescriptor descriptor) =>
- descriptor != null && descriptor.PropertyBag.ContainsKey(ViewComponentNameKey);
+ descriptor != null && descriptor.Metadata.ContainsKey(ViewComponentNameKey);
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperPass.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperPass.cs
index da7107c281..1f7ec7080a 100644
--- a/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperPass.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperPass.cs
@@ -1,8 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Evolution;
@@ -28,7 +28,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
{
GenerateVCTHClass(visitor.Class, tagHelper.Value);
- if (visitor.Fields.UsedTagHelperTypeNames.Remove(tagHelper.Value.TypeName))
+ var tagHelperTypeName = tagHelper.Value.Metadata[ITagHelperDescriptorBuilder.TypeNameKey];
+ if (visitor.Fields.UsedTagHelperTypeNames.Remove(tagHelperTypeName))
{
visitor.Fields.UsedTagHelperTypeNames.Add(GetVCTHFullName(visitor.Namespace, visitor.Class, tagHelper.Value));
}
@@ -77,14 +78,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
ClassDeclarationIRNode @class,
TagHelperDescriptor tagHelper)
{
- var vcName = tagHelper.PropertyBag[ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey];
+ var vcName = tagHelper.Metadata[ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey];
return $"{@namespace.Content}.{@class.Name}.__Generated__{vcName}ViewComponentTagHelper";
}
private static string GetVCTHClassName(
TagHelperDescriptor tagHelper)
{
- var vcName = tagHelper.PropertyBag[ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey];
+ var vcName = tagHelper.Metadata[ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey];
return $"__Generated__{vcName}ViewComponentTagHelper";
}
@@ -143,18 +144,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
$"global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext",
"ViewContext");
- var indexerAttributes = descriptor.Attributes.Where(a => a.IsIndexer);
-
- foreach (var attribute in descriptor.Attributes)
+ foreach (var attribute in descriptor.BoundAttributes)
{
- if (attribute.IsIndexer)
- {
- continue;
- }
+ writer.WriteAutoPropertyDeclaration(
+ "public", attribute.TypeName, attribute.Metadata[ITagHelperBoundAttributeDescriptorBuilder.PropertyNameKey]);
- writer.WriteAutoPropertyDeclaration("public", attribute.TypeName, attribute.PropertyName);
-
- if (indexerAttributes.Any(a => string.Equals(a.PropertyName, attribute.PropertyName, StringComparison.Ordinal)))
+ if (attribute.IndexerTypeName != null)
{
writer.Write(" = ")
.WriteStartNewObject(attribute.TypeName)
@@ -199,11 +194,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
private string[] GetMethodParameters(TagHelperDescriptor descriptor)
{
- var propertyNames = descriptor.Attributes.Where(a => !a.IsIndexer).Select(attribute => attribute.PropertyName);
+ var propertyNames = descriptor.BoundAttributes.Select(
+ attribute => attribute.Metadata[ITagHelperBoundAttributeDescriptorBuilder.PropertyNameKey]);
var joinedPropertyNames = string.Join(", ", propertyNames);
var parametersString = $"new {{ { joinedPropertyNames } }}";
- var viewComponentName = descriptor.PropertyBag[
+ var viewComponentName = descriptor.Metadata[
ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey];
var methodParameters = new[] { $"\"{viewComponentName}\"", parametersString };
return methodParameters;
@@ -211,9 +207,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
private void BuildTargetElementString(CSharpCodeWriter writer, TagHelperDescriptor descriptor)
{
+ Debug.Assert(descriptor.TagMatchingRules.Count() == 1);
+
+ var rule = descriptor.TagMatchingRules.First();
+
writer.Write("[")
.WriteStartMethodInvocation("Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute")
- .WriteStringLiteral(descriptor.FullTagName)
+ .WriteStringLiteral(rule.TagName)
.WriteLine(")]");
}
@@ -235,7 +235,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
if (ViewComponentTagHelperDescriptorConventions.IsViewComponentDescriptor(tagHelper))
{
// Capture all the VCTagHelpers (unique by type name) so we can generate a class for each one.
- var vcName = tagHelper.PropertyBag[ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey];
+ var vcName = tagHelper.Metadata[ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey];
TagHelpers[vcName] = tagHelper;
CreateTagHelpers.Add(node);
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ModelExpressionPassTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ModelExpressionPassTest.cs
index daaf6d0b5a..3998336a34 100644
--- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ModelExpressionPassTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ModelExpressionPassTest.cs
@@ -25,21 +25,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
var tagHelpers = new[]
{
- new TagHelperDescriptor()
- {
- AssemblyName = "TestAssembly",
- TypeName = "TestTagHelper",
- TagName = "p",
- Attributes = new TagHelperAttributeDescriptor[]
- {
- new TagHelperAttributeDescriptor()
- {
- TypeName = "System.Int32",
- Name = "Foo",
- }
-
- }
- }
+ ITagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly")
+ .BindAttribute(attribute =>
+ attribute
+ .Name("Foo")
+ .TypeName("System.Int32"))
+ .TagMatchingRule(rule =>
+ rule.RequireTagName("p"))
+ .Build()
};
var engine = CreateEngine(tagHelpers);
@@ -72,21 +65,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
var tagHelpers = new[]
{
- new TagHelperDescriptor()
- {
- AssemblyName = "TestAssembly",
- TypeName = "TestTagHelper",
- TagName = "p",
- Attributes = new TagHelperAttributeDescriptor[]
- {
- new TagHelperAttributeDescriptor()
- {
- TypeName = typeof(ModelExpression).FullName,
- Name = "Foo",
- }
-
- }
- }
+ ITagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly")
+ .BindAttribute(attribute =>
+ attribute
+ .Name("Foo")
+ .TypeName(typeof(ModelExpression).FullName))
+ .TagMatchingRule(rule =>
+ rule.RequireTagName("p"))
+ .Build()
};
var engine = CreateEngine(tagHelpers);
@@ -124,21 +110,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
var tagHelpers = new[]
{
- new TagHelperDescriptor()
- {
- AssemblyName = "TestAssembly",
- TypeName = "TestTagHelper",
- TagName = "p",
- Attributes = new TagHelperAttributeDescriptor[]
- {
- new TagHelperAttributeDescriptor()
- {
- TypeName = typeof(ModelExpression).FullName,
- Name = "Foo",
- }
-
- }
- }
+ ITagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly")
+ .BindAttribute(attribute =>
+ attribute
+ .Name("Foo")
+ .TypeName(typeof(ModelExpression).FullName))
+ .TagMatchingRule(rule =>
+ rule.RequireTagName("p"))
+ .Build()
};
var engine = CreateEngine(tagHelpers);
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperDescriptorConventionsTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperDescriptorConventionsTest.cs
index 9eb24f8437..bcfbfee65c 100644
--- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperDescriptorConventionsTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperDescriptorConventionsTest.cs
@@ -38,22 +38,22 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host.Test
private static TagHelperDescriptor CreateTagHelperDescriptor()
{
- var descriptor = new TagHelperDescriptor
- {
- TagName = "tag-name",
- TypeName = "TypeName",
- AssemblyName = "AssemblyName",
- };
+ var descriptor = ITagHelperDescriptorBuilder.Create("TypeName", "AssemblyName")
+ .TagMatchingRule(rule =>
+ rule.RequireTagName("tag-name"))
+ .Build();
+
return descriptor;
}
private static TagHelperDescriptor CreateViewComponentTagHelperDescriptor()
{
- var descriptor = CreateTagHelperDescriptor();
- descriptor.PropertyBag.Add(
- ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey,
- "ViewComponentName");
+ var descriptor = ITagHelperDescriptorBuilder.Create("TypeName", "AssemblyName")
+ .TagMatchingRule(rule =>
+ rule.RequireTagName("tag-name"))
+ .AddMetadata(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "ViewComponentName")
+ .Build();
return descriptor;
}
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperPassTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperPassTest.cs
index e71a1554f9..5b34d47e7e 100644
--- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperPassTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperPassTest.cs
@@ -23,20 +23,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
var tagHelpers = new[]
{
- new TagHelperDescriptor()
- {
- AssemblyName = "TestAssembly",
- TypeName = "TestTagHelper",
- TagName = "p",
- Attributes = new TagHelperAttributeDescriptor[]
- {
- new TagHelperAttributeDescriptor()
- {
- TypeName = "System.Int32",
- Name = "Foo",
- }
- }
- }
+ ITagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly")
+ .BindAttribute(attribute =>
+ attribute
+ .Name("Foo")
+ .TypeName("System.Int32"))
+ .TagMatchingRule(rule =>
+ rule.RequireTagName("p"))
+ .Build()
};
var engine = CreateEngine(tagHelpers);
@@ -69,25 +63,18 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host
var tagHelpers = new[]
{
- new TagHelperDescriptor()
- {
- AssemblyName = "TestAssembly",
- TypeName = "TestTagHelper",
- TagName = "tagcloud",
- Attributes = new TagHelperAttributeDescriptor[]
- {
- new TagHelperAttributeDescriptor()
- {
- TypeName = "System.Int32",
- Name = "Foo",
- PropertyName = "Foo",
- }
- }
- }
+ ITagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly")
+ .BindAttribute(attribute =>
+ attribute
+ .Name("Foo")
+ .TypeName("System.Int32")
+ .PropertyName("Foo"))
+ .TagMatchingRule(rule =>
+ rule.RequireTagName("tagcloud"))
+ .AddMetadata(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "TagCloud")
+ .Build()
};
- tagHelpers[0].PropertyBag.Add(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "TagCloud");
-
var engine = CreateEngine(tagHelpers);
var pass = new ViewComponentTagHelperPass()
{
@@ -146,33 +133,19 @@ public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore.
var tagHelpers = new[]
{
- new TagHelperDescriptor()
- {
- AssemblyName = "TestAssembly",
- TypeName = "TestTagHelper",
- TagName = "tagcloud",
- Attributes = new TagHelperAttributeDescriptor[]
- {
- new TagHelperAttributeDescriptor()
- {
- TypeName = "System.Collections.Generic.Dictionary",
- Name = "foo",
- PropertyName = "Tags",
- IsIndexer = false,
- },
- new TagHelperAttributeDescriptor()
- {
- TypeName = "System.Collections.Generic.Dictionary",
- Name = "foo-",
- PropertyName = "Tags",
- IsIndexer = true,
- }
- }
- }
+ ITagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly")
+ .BindAttribute(attribute =>
+ attribute
+ .Name("Foo")
+ .TypeName("System.Collections.Generic.Dictionary")
+ .PropertyName("Tags")
+ .AsDictionary("foo-", "System.Int32"))
+ .TagMatchingRule(rule =>
+ rule.RequireTagName("tagcloud"))
+ .AddMetadata(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "TagCloud")
+ .Build()
};
- tagHelpers[0].PropertyBag.Add(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "TagCloud");
-
var engine = CreateEngine(tagHelpers);
var pass = new ViewComponentTagHelperPass()
{
@@ -231,39 +204,26 @@ public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore.
var tagHelpers = new[]
{
- new TagHelperDescriptor()
- {
- AssemblyName = "TestAssembly",
- TypeName = "PTestTagHelper",
- TagName = "p",
- Attributes = new TagHelperAttributeDescriptor[]
- {
- new TagHelperAttributeDescriptor()
- {
- TypeName = "System.Int32",
- Name = "Foo",
- }
- }
- },
- new TagHelperDescriptor()
- {
- AssemblyName = "TestAssembly",
- TypeName = "TestTagHelper",
- TagName = "tagcloud",
- Attributes = new TagHelperAttributeDescriptor[]
- {
- new TagHelperAttributeDescriptor()
- {
- TypeName = "System.Int32",
- Name = "Foo",
- PropertyName = "Foo",
- }
- }
- }
+ ITagHelperDescriptorBuilder.Create("PTestTagHelper", "TestAssembly")
+ .BindAttribute(attribute =>
+ attribute
+ .Name("Foo")
+ .TypeName("System.Int32"))
+ .TagMatchingRule(rule =>
+ rule.RequireTagName("p"))
+ .Build(),
+ ITagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly")
+ .BindAttribute(attribute =>
+ attribute
+ .Name("Foo")
+ .TypeName("System.Int32")
+ .PropertyName("Foo"))
+ .TagMatchingRule(rule =>
+ rule.RequireTagName("tagcloud"))
+ .AddMetadata(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "TagCloud")
+ .Build()
};
- tagHelpers[1].PropertyBag.Add(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "TagCloud");
-
var engine = CreateEngine(tagHelpers);
var pass = new ViewComponentTagHelperPass()
{