| File: ModelExpressionProvider.cs | Web Access |
| Project: src\aspnetcore\src\Mvc\Mvc.ViewFeatures\src\Microsoft.AspNetCore.Mvc.ViewFeatures.csproj (Microsoft.AspNetCore.Mvc.ViewFeatures) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Concurrent; using System.Linq.Expressions; using Microsoft.AspNetCore.Mvc.ModelBinding; namespace Microsoft.AspNetCore.Mvc.ViewFeatures; /// <summary> /// Provides <see cref="ModelExpression"/> for expressions. /// </summary> public class ModelExpressionProvider : IModelExpressionProvider { private readonly IModelMetadataProvider _modelMetadataProvider; private readonly ConcurrentDictionary<LambdaExpression, string> _expressionTextCache; /// <summary> /// Creates a new <see cref="ModelExpressionProvider"/>. /// </summary> /// <param name="modelMetadataProvider">The <see cref="IModelMetadataProvider"/>.</param> public ModelExpressionProvider(IModelMetadataProvider modelMetadataProvider) { ArgumentNullException.ThrowIfNull(modelMetadataProvider); _modelMetadataProvider = modelMetadataProvider; _expressionTextCache = new ConcurrentDictionary<LambdaExpression, string>(LambdaExpressionComparer.Instance); } /// <summary> /// Gets the name for <paramref name="expression"/>. /// </summary> /// <typeparam name="TModel">The model type.</typeparam> /// <typeparam name="TValue">The type of the <paramref name="expression"/> result.</typeparam> /// <param name="expression">The expression.</param> /// <returns>The expression name.</returns> public string GetExpressionText<TModel, TValue>(Expression<Func<TModel, TValue>> expression) { ArgumentNullException.ThrowIfNull(expression); return ExpressionHelper.GetExpressionText(expression, _expressionTextCache); } /// <inheritdoc /> public ModelExpression CreateModelExpression<TModel, TValue>( ViewDataDictionary<TModel> viewData, Expression<Func<TModel, TValue>> expression) { ArgumentNullException.ThrowIfNull(viewData); ArgumentNullException.ThrowIfNull(expression); var name = GetExpressionText(expression); var modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, viewData, _modelMetadataProvider); if (modelExplorer == null) { throw new InvalidOperationException( Resources.FormatCreateModelExpression_NullModelMetadata(nameof(IModelMetadataProvider), name)); } return new ModelExpression(name, modelExplorer); } /// <summary> /// Returns a <see cref="ModelExpression"/> instance describing the given <paramref name="expression"/>. /// </summary> /// <typeparam name="TModel">The type of the <paramref name="viewData"/>'s <see cref="ViewDataDictionary{T}.Model"/>.</typeparam> /// <param name="viewData">The <see cref="ViewDataDictionary{TModel}"/> containing the <see cref="ViewDataDictionary{T}.Model"/> /// against which <paramref name="expression"/> is evaluated. </param> /// <param name="expression">Expression name, relative to <c>viewData.Model</c>.</param> /// <returns>A new <see cref="ModelExpression"/> instance describing the given <paramref name="expression"/>.</returns> public ModelExpression CreateModelExpression<TModel>( ViewDataDictionary<TModel> viewData, string expression) { ArgumentNullException.ThrowIfNull(viewData); ArgumentNullException.ThrowIfNull(expression); var modelExplorer = ExpressionMetadataProvider.FromStringExpression(expression, viewData, _modelMetadataProvider); if (modelExplorer == null) { throw new InvalidOperationException( Resources.FormatCreateModelExpression_NullModelMetadata(nameof(IModelMetadataProvider), expression)); } return new ModelExpression(expression, modelExplorer); } }