Address PR comments

This commit is contained in:
Doug Bunting 2015-02-16 22:00:53 -08:00
parent 8eb63271b5
commit 966bfeb8c1
5 changed files with 23 additions and 18 deletions

View File

@ -25,10 +25,10 @@ namespace Microsoft.AspNet.Mvc.Rendering.Expressions
{ {
private static Func<TModel, TResult> _identityFunc; private static Func<TModel, TResult> _identityFunc;
private static readonly ConcurrentDictionary<MemberInfo, Func<TModel, TResult>> _simpleMemberAccessDict = private static readonly ConcurrentDictionary<MemberInfo, Func<TModel, TResult>> _simpleMemberAccessCache =
new ConcurrentDictionary<MemberInfo, Func<TModel, TResult>>(); new ConcurrentDictionary<MemberInfo, Func<TModel, TResult>>();
private static readonly ConcurrentDictionary<MemberInfo, Func<object, TResult>> _constMemberAccessDict = private static readonly ConcurrentDictionary<MemberInfo, Func<object, TResult>> _constMemberAccessCache =
new ConcurrentDictionary<MemberInfo, Func<object, TResult>>(); new ConcurrentDictionary<MemberInfo, Func<object, TResult>>();
public static Func<TModel, TResult> Compile([NotNull] Expression<Func<TModel, TResult>> expression) public static Func<TModel, TResult> Compile([NotNull] Expression<Func<TModel, TResult>> expression)
@ -88,23 +88,25 @@ namespace Microsoft.AspNet.Mvc.Rendering.Expressions
if (memberExpression.Expression == expression.Parameters[0] || memberExpression.Expression == null) if (memberExpression.Expression == expression.Parameters[0] || memberExpression.Expression == null)
{ {
// model => model.Member or model => StaticMember // model => model.Member or model => StaticMember
return _simpleMemberAccessDict.GetOrAdd(memberExpression.Member, _ => expression.Compile()); return _simpleMemberAccessCache.GetOrAdd(memberExpression.Member, _ => expression.Compile());
} }
var constantExpression = memberExpression.Expression as ConstantExpression; var constantExpression = memberExpression.Expression as ConstantExpression;
if (constantExpression != null) if (constantExpression != null)
{ {
// model => {const}.Member (captured local variable) // model => {const}.Member (captured local variable)
var compiledExpression = _constMemberAccessDict.GetOrAdd(memberExpression.Member, _ => var compiledExpression = _constMemberAccessCache.GetOrAdd(memberExpression.Member, _ =>
{ {
// rewrite as capturedLocal => ((TDeclaringType)capturedLocal).Member // rewrite as capturedLocal => ((TDeclaringType)capturedLocal).Member
var parameterExpression = Expression.Parameter(typeof(object), "capturedLocal"); var parameterExpression = Expression.Parameter(typeof(object), "capturedLocal");
var castExpression = var castExpression =
Expression.Convert(parameterExpression, memberExpression.Member.DeclaringType); Expression.Convert(parameterExpression, memberExpression.Member.DeclaringType);
var newMemberExpression = memberExpression.Update(castExpression); var replacementMemberExpression = memberExpression.Update(castExpression);
var newExpression = var replacementExpression = Expression.Lambda<Func<object, TResult>>(
Expression.Lambda<Func<object, TResult>>(newMemberExpression, parameterExpression); replacementMemberExpression,
return newExpression.Compile(); parameterExpression);
return replacementExpression.Compile();
}); });
var capturedLocal = constantExpression.Value; var capturedLocal = constantExpression.Value;

View File

@ -224,8 +224,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
var serviceProvider = htmlHelper.ViewContext.HttpContext.RequestServices; var serviceProvider = htmlHelper.ViewContext.HttpContext.RequestServices;
var viewEngine = serviceProvider.GetRequiredService<ICompositeViewEngine>(); var viewEngine = serviceProvider.GetRequiredService<ICompositeViewEngine>();
var properties = modelMetadata.Properties.Where(metadata => ShouldShow(metadata, templateInfo));
foreach (var propertyMetadata in modelMetadata.Properties.Where(pm => ShouldShow(pm, templateInfo))) foreach (var propertyMetadata in properties)
{ {
var divTag = new TagBuilder("div"); var divTag = new TagBuilder("div");

View File

@ -248,8 +248,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
var serviceProvider = htmlHelper.ViewContext.HttpContext.RequestServices; var serviceProvider = htmlHelper.ViewContext.HttpContext.RequestServices;
var viewEngine = serviceProvider.GetRequiredService<ICompositeViewEngine>(); var viewEngine = serviceProvider.GetRequiredService<ICompositeViewEngine>();
var properties = modelMetadata.Properties.Where(metadata => ShouldShow(metadata, templateInfo));
foreach (var propertyMetadata in modelMetadata.Properties.Where(pm => ShouldShow(pm, templateInfo))) foreach (var propertyMetadata in properties)
{ {
var divTag = new TagBuilder("div"); var divTag = new TagBuilder("div");
@ -315,8 +315,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
{ {
return return
metadata.ShowForEdit && metadata.ShowForEdit &&
!metadata.IsComplexType !metadata.IsComplexType &&
&& !templateInfo.Visited(metadata); !templateInfo.Visited(metadata);
} }
public static string StringTemplate(IHtmlHelper htmlHelper) public static string StringTemplate(IHtmlHelper htmlHelper)

View File

@ -1024,14 +1024,17 @@ namespace Microsoft.AspNet.Mvc.Rendering
if (value == null) if (value == null)
{ {
throw new InvalidOperationException(Resources.FormatHtmlHelper_MissingSelectData( throw new InvalidOperationException(Resources.FormatHtmlHelper_MissingSelectData(
"IEnumerable<SelectListItem>", expression)); $"IEnumerable<{nameof(SelectListItem)}>",
expression));
} }
var selectList = value as IEnumerable<SelectListItem>; var selectList = value as IEnumerable<SelectListItem>;
if (selectList == null) if (selectList == null)
{ {
throw new InvalidOperationException(Resources.FormatHtmlHelper_WrongSelectDataType( throw new InvalidOperationException(Resources.FormatHtmlHelper_WrongSelectDataType(
expression, value.GetType().FullName, "IEnumerable<SelectListItem>")); expression,
value.GetType().FullName,
$"IEnumerable<{nameof(SelectListItem)}>"));
} }
return selectList; return selectList;

View File

@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
if (viewContext.ViewData == null) if (viewContext.ViewData == null)
{ {
throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull( throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull(
"ViewData", nameof(ViewContext.ViewData),
typeof(ViewContext)), typeof(ViewContext)),
nameof(viewContext)); nameof(viewContext));
} }
@ -41,7 +41,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
{ {
// viewContext may contain a base ViewDataDictionary instance. So complain about that type, not TModel. // viewContext may contain a base ViewDataDictionary instance. So complain about that type, not TModel.
throw new ArgumentException(Resources.FormatArgumentPropertyUnexpectedType( throw new ArgumentException(Resources.FormatArgumentPropertyUnexpectedType(
"ViewData", nameof(ViewContext.ViewData),
viewContext.ViewData.GetType().FullName, viewContext.ViewData.GetType().FullName,
typeof(ViewDataDictionary<TModel>).FullName), typeof(ViewDataDictionary<TModel>).FullName),
nameof(viewContext)); nameof(viewContext));