// 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 System.Collections.Concurrent; using System.Linq; using System.Text; using Microsoft.AspNet.Mvc.Razor.Internal; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.Razor { /// /// Default implementation of . /// public class DefaultViewLocationCache : IViewLocationCache { private const char CacheKeySeparator = ':'; // A mapping of keys generated from ViewLocationExpanderContext to view locations. private readonly ConcurrentDictionary _cache; /// /// Initializes a new instance of . /// public DefaultViewLocationCache() { _cache = new ConcurrentDictionary(StringComparer.Ordinal); } /// public string Get([NotNull] ViewLocationExpanderContext context) { var cacheKey = GenerateKey(context); string result; _cache.TryGetValue(cacheKey, out result); return result; } /// public void Set([NotNull] ViewLocationExpanderContext context, [NotNull] string value) { var cacheKey = GenerateKey(context); _cache.TryAdd(cacheKey, value); } internal static string GenerateKey(ViewLocationExpanderContext context) { var keyBuilder = new StringBuilder(); var routeValues = context.ActionContext.RouteData.Values; var controller = RazorViewEngine.GetNormalizedRouteValue( context.ActionContext, RazorViewEngine.ControllerKey); // format is "{viewName}:{isPartial}:{controllerName}:{areaName}:" keyBuilder.Append(context.ViewName) .Append(CacheKeySeparator) .Append(context.IsPartial ? 1 : 0) .Append(CacheKeySeparator) .Append(controller); var area = RazorViewEngine.GetNormalizedRouteValue(context.ActionContext, RazorViewEngine.AreaKey); if (!string.IsNullOrEmpty(area)) { keyBuilder.Append(CacheKeySeparator) .Append(area); } if (context.Values != null) { var valuesDictionary = context.Values; foreach (var item in valuesDictionary.OrderBy(k => k.Key, StringComparer.Ordinal)) { keyBuilder.Append(CacheKeySeparator) .Append(item.Key) .Append(CacheKeySeparator) .Append(item.Value); } } var cacheKey = keyBuilder.ToString(); return cacheKey; } } }