| File: Mvc\ViewComponentTagHelperTargetExtension.cs | Web Access |
| Project: src\roslyn\src\Razor\src\Compiler\Microsoft.CodeAnalysis.Razor.Compiler\src\Microsoft.CodeAnalysis.Razor.Compiler.csproj (Microsoft.CodeAnalysis.Razor.Compiler) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Immutable; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.CodeGeneration; using Microsoft.AspNetCore.Razor.Language.Intermediate; namespace Microsoft.AspNetCore.Mvc.Razor.Extensions; internal sealed class ViewComponentTagHelperTargetExtension : ViewComponentTagHelperTargetExtensionBase { private ImmutableArray<MethodParameter> _processInvokeAsyncArgsMethodParameters; private ImmutableArray<MethodParameter> ProcessInvokeAsyncArgsMethodParameters { get { if (_processInvokeAsyncArgsMethodParameters.IsDefault) { ImmutableInterlocked.InterlockedInitialize(ref _processInvokeAsyncArgsMethodParameters, [new(TagHelperContextVariableName, ViewComponentsApi.TagHelperContext.FullTypeName)]); } return _processInvokeAsyncArgsMethodParameters; } } protected override string TagHelperContentVariableName => "__helperContent"; protected override string TagHelperContextVariableName => "__context"; protected override string TagHelperOutputVariableName => "__output"; protected override string ViewComponentHelperVariableName => "__helper"; protected override void WriteAdditionalMembers(CodeRenderingContext context, ViewComponentTagHelperIntermediateNode node) { // We pre-process the arguments passed to `InvokeAsync` to ensure that the // provided markup attributes (in kebab-case) are matched to the associated // properties in the VCTH class. WriteProcessInvokeAsyncArgsMethodString(context.CodeWriter, node.TagHelper); } private void WriteProcessInvokeAsyncArgsMethodString(CodeWriter writer, TagHelperDescriptor tagHelper) { const string DictionaryType = "Dictionary<string, object>"; using (writer.BuildMethodDeclaration( CommonModifiers.Private, DictionaryType, ViewComponentsApi.ProcessInvokeAsyncArgsMethodName, ProcessInvokeAsyncArgsMethodParameters)) { writer.WriteStartAssignment($"{DictionaryType} args") .WriteStartNewObject(DictionaryType) .WriteEndMethodInvocation(); foreach (var attribute in tagHelper.BoundAttributes) { var attributeName = attribute.Name; var parameterName = attribute.PropertyName; writer.WriteLine($"if (__context.AllAttributes.ContainsName(\"{attributeName}\"))"); using (writer.BuildScope()) { writer.WriteLine($"args[nameof({parameterName})] = {parameterName};"); } } writer.WriteLine("return args;"); } } protected override ImmutableArray<string> GetInvokeArguments(TagHelperDescriptor tagHelper) { var viewComponentName = tagHelper.ViewComponentName; return [$"\"{viewComponentName}\"", $"{ViewComponentsApi.ProcessInvokeAsyncArgsMethodName}({TagHelperContextVariableName})"]; } }