зеркало из https://github.com/aspnet/Mvc.git
Add ModelExpression code generation.
- Sealed the ModelExpression. - We use the stringified version of the ModelExpression type name to detect ModelExpression properties on TagHelpers. This is so the MvcRazorHost can work in tooling and in runtime. - Created a GeneratedTagHelperAttributeContext to represent the specific stringified versions of the ModelExpression assets. - Created an MvcTagHelperAttributeValueCodeRenderer to modify rendering of ModelExpression properties. #1241
This commit is contained in:
Родитель
ad76a3c8fb
Коммит
2005c3cd85
|
@ -10,7 +10,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
/// <summary>
|
||||
/// Describes an <see cref="System.Linq.Expressions.Expression"/> passed to a tag helper.
|
||||
/// </summary>
|
||||
public class ModelExpression
|
||||
public sealed class ModelExpression
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ModelExpression"/> class.
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information for the <see cref="ITagHelper"/> attribute code generation process.
|
||||
/// </summary>
|
||||
public class GeneratedTagHelperAttributeContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the model expression type.
|
||||
/// </summary>
|
||||
public string ModelExpressionTypeName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name the method to create <c>ModelExpression</c>s.
|
||||
/// </summary>
|
||||
public string CreateModelExpressionMethodName { get; set; }
|
||||
}
|
||||
}
|
|
@ -11,20 +11,34 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
{
|
||||
public class MvcCSharpCodeBuilder : CSharpCodeBuilder
|
||||
{
|
||||
private readonly GeneratedTagHelperAttributeContext _tagHelperAttributeContext;
|
||||
private readonly string _defaultModel;
|
||||
private readonly string _activateAttribute;
|
||||
|
||||
public MvcCSharpCodeBuilder([NotNull] CodeBuilderContext context,
|
||||
[NotNull] string defaultModel,
|
||||
[NotNull] string activateAttribute)
|
||||
[NotNull] string activateAttribute,
|
||||
[NotNull] GeneratedTagHelperAttributeContext tagHelperAttributeContext)
|
||||
: base(context)
|
||||
{
|
||||
_tagHelperAttributeContext = tagHelperAttributeContext;
|
||||
_defaultModel = defaultModel;
|
||||
_activateAttribute = activateAttribute;
|
||||
}
|
||||
|
||||
private string Model { get; set; }
|
||||
|
||||
protected override CSharpCodeVisitor CreateCSharpCodeVisitor([NotNull] CSharpCodeWriter writer,
|
||||
[NotNull] CodeBuilderContext context)
|
||||
{
|
||||
var csharpCodeVisitor = base.CreateCSharpCodeVisitor(writer, context);
|
||||
|
||||
csharpCodeVisitor.TagHelperRenderer.AttributeValueCodeRenderer =
|
||||
new MvcTagHelperAttributeValueCodeRenderer(_tagHelperAttributeContext);
|
||||
|
||||
return csharpCodeVisitor;
|
||||
}
|
||||
|
||||
protected override CSharpCodeWritingScope BuildClassDeclaration(CSharpCodeWriter writer)
|
||||
{
|
||||
// Grab the last model chunk so it gets intellisense.
|
||||
|
|
|
@ -153,6 +153,22 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
get { return "Microsoft.AspNet.Mvc.ActivateAttribute"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type name used to represent <see cref="ITagHelper"/> model expression properties.
|
||||
/// </summary>
|
||||
public virtual string ModelExpressionType
|
||||
{
|
||||
get { return "Microsoft.AspNet.Mvc.Rendering.ModelExpression"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the method name used to create model expressions.
|
||||
/// </summary>
|
||||
public virtual string CreateModelExpressionMethod
|
||||
{
|
||||
get { return "CreateModelExpression"; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public GeneratorResults GenerateCode(string rootRelativePath, Stream inputStream)
|
||||
{
|
||||
|
@ -173,7 +189,15 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
[NotNull] CodeBuilderContext context)
|
||||
{
|
||||
UpdateCodeBuilder(context);
|
||||
return new MvcCSharpCodeBuilder(context, DefaultModel, ActivateAttribute);
|
||||
|
||||
return new MvcCSharpCodeBuilder(context,
|
||||
DefaultModel,
|
||||
ActivateAttribute,
|
||||
new GeneratedTagHelperAttributeContext
|
||||
{
|
||||
ModelExpressionTypeName = ModelExpressionType,
|
||||
CreateModelExpressionMethodName = CreateModelExpressionMethod
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateCodeBuilder(CodeGeneratorContext context)
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.Razor.Generator;
|
||||
using Microsoft.AspNet.Razor.Generator.Compiler.CSharp;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class MvcTagHelperAttributeValueCodeRenderer : TagHelperAttributeValueCodeRenderer
|
||||
{
|
||||
private const string ModelLambdaVariableName = "__model";
|
||||
|
||||
private readonly GeneratedTagHelperAttributeContext _context;
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates a new instance of <see cref="MvcTagHelperAttributeValueCodeRenderer"/>.
|
||||
/// </summary>
|
||||
/// <param name="context">Contains code generation information for rendering attribute values.</param>
|
||||
public MvcTagHelperAttributeValueCodeRenderer([NotNull] GeneratedTagHelperAttributeContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks>If the attribute being rendered is of the type
|
||||
/// <see cref="GeneratedTagHelperAttributeContext.ModelExpressionTypeName"/> then a model expression will be
|
||||
/// created by calling into <see cref="GeneratedTagHelperAttributeContext.CreateModelExpressionMethodName"/>.
|
||||
/// </remarks>
|
||||
public override void RenderAttributeValue([NotNull] TagHelperAttributeDescriptor attributeDescriptor,
|
||||
[NotNull] CSharpCodeWriter writer,
|
||||
[NotNull] CodeBuilderContext codeBuilderContext,
|
||||
[NotNull] Action<CSharpCodeWriter> renderAttributeValue)
|
||||
{
|
||||
var propertyType = attributeDescriptor.PropertyInfo.PropertyType;
|
||||
|
||||
if (propertyType.FullName.Equals(_context.ModelExpressionTypeName, StringComparison.Ordinal))
|
||||
{
|
||||
writer.WriteStartMethodInvocation(_context.CreateModelExpressionMethodName)
|
||||
.Write(ModelLambdaVariableName)
|
||||
.Write(" => ")
|
||||
.Write(ModelLambdaVariableName)
|
||||
.Write(".");
|
||||
|
||||
renderAttributeValue(writer);
|
||||
|
||||
writer.WriteEndMethodInvocation(endLine: false);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.RenderAttributeValue(attributeDescriptor, writer, codeBuilderContext, renderAttributeValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче