[Perf] UrlHelper shares a single RouteValueDictionary across several calls to Action and RouteUrl methods
This commit is contained in:
parent
d7ccea17ce
commit
df4eb283b2
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
@ -18,6 +19,8 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
|
|
||||||
// Perf: Share the StringBuilder object across multiple calls of GenerateURL for this UrlHelper
|
// Perf: Share the StringBuilder object across multiple calls of GenerateURL for this UrlHelper
|
||||||
private StringBuilder _stringBuilder;
|
private StringBuilder _stringBuilder;
|
||||||
|
// Perf: Reuse the RouteValueDictionary across multiple calls of Action for this UrlHelper
|
||||||
|
private readonly RouteValueDictionary _routeValueDictionary;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="UrlHelper"/> class using the specified action context and
|
/// Initializes a new instance of the <see cref="UrlHelper"/> class using the specified action context and
|
||||||
|
|
@ -32,6 +35,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionContext = actionContext;
|
ActionContext = actionContext;
|
||||||
|
_routeValueDictionary = new RouteValueDictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -51,7 +55,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
throw new ArgumentNullException(nameof(actionContext));
|
throw new ArgumentNullException(nameof(actionContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
var valuesDictionary = new RouteValueDictionary(actionContext.Values);
|
var valuesDictionary = GetValuesDictionary(actionContext.Values);
|
||||||
|
|
||||||
if (actionContext.Action == null)
|
if (actionContext.Action == null)
|
||||||
{
|
{
|
||||||
|
|
@ -106,7 +110,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
throw new ArgumentNullException(nameof(routeContext));
|
throw new ArgumentNullException(nameof(routeContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
var valuesDictionary = new RouteValueDictionary(routeContext.Values);
|
var valuesDictionary = routeContext.Values as RouteValueDictionary ?? GetValuesDictionary(routeContext.Values);
|
||||||
var virtualPathData = GetVirtualPathData(routeContext.RouteName, valuesDictionary);
|
var virtualPathData = GetVirtualPathData(routeContext.RouteName, valuesDictionary);
|
||||||
return GenerateUrl(routeContext.Protocol, routeContext.Host, virtualPathData, routeContext.Fragment);
|
return GenerateUrl(routeContext.Protocol, routeContext.Host, virtualPathData, routeContext.Fragment);
|
||||||
}
|
}
|
||||||
|
|
@ -205,6 +209,37 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private RouteValueDictionary GetValuesDictionary(object values)
|
||||||
|
{
|
||||||
|
// Perf: RouteValueDictionary can be cast to IDictionary<string, object>, but it is
|
||||||
|
// special cased to avoid allocating boxed Enumerator.
|
||||||
|
var routeValuesDictionary = values as RouteValueDictionary;
|
||||||
|
if (routeValuesDictionary != null)
|
||||||
|
{
|
||||||
|
_routeValueDictionary.Clear();
|
||||||
|
foreach (var kvp in routeValuesDictionary)
|
||||||
|
{
|
||||||
|
_routeValueDictionary.Add(kvp.Key, kvp.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _routeValueDictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dictionaryValues = values as IDictionary<string, object>;
|
||||||
|
if (dictionaryValues != null)
|
||||||
|
{
|
||||||
|
_routeValueDictionary.Clear();
|
||||||
|
foreach (var kvp in dictionaryValues)
|
||||||
|
{
|
||||||
|
_routeValueDictionary.Add(kvp.Key, kvp.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _routeValueDictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RouteValueDictionary(values);
|
||||||
|
}
|
||||||
|
|
||||||
private StringBuilder GetStringBuilder()
|
private StringBuilder GetStringBuilder()
|
||||||
{
|
{
|
||||||
if(_stringBuilder == null)
|
if(_stringBuilder == null)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue