Private cache for cache tag helper and distributed cache tag helper
This commit is contained in:
parent
65fce8dd65
commit
3d76fdf086
|
|
@ -2,15 +2,10 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Antiforgery;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Internal;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace MvcSandbox
|
||||
{
|
||||
|
|
@ -20,11 +15,6 @@ namespace MvcSandbox
|
|||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddMvc();
|
||||
services.AddSingleton<IFileProvider>(new PhysicalFileProvider(Path.GetFullPath(".")));
|
||||
|
||||
services.Insert(0, ServiceDescriptor.Singleton(
|
||||
typeof(IConfigureOptions<AntiforgeryOptions>),
|
||||
new ConfigureOptions<AntiforgeryOptions>(options => options.Cookie.Name = "<choose a name>")));
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
|
|
|
|||
|
|
@ -9,4 +9,4 @@
|
|||
<li>This sandbox should give you a quick view of a basic MVC application.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="refresh" content="1">
|
||||
<title>@ViewData["Title"] - MvcSandbox</title>
|
||||
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.5/css/bootstrap.min.css" />
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -85,6 +85,9 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers.Cache
|
|||
// Is there any request already processing the value?
|
||||
if (!_workers.TryGetValue(key, out result))
|
||||
{
|
||||
// There is a small race condition here between TryGetValue and TryAdd that might cause the
|
||||
// content to be computed more than once. We don't care about this race as the probability of
|
||||
// happening is very small and the impact is not critical.
|
||||
var tcs = new TaskCompletionSource<IHtmlContent>();
|
||||
|
||||
_workers.TryAdd(key, tcs.Task);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Mvc.TagHelpers.Cache;
|
||||
using Microsoft.AspNetCore.Mvc.TagHelpers.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
|
@ -29,14 +30,22 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
|
||||
private const string CachePriorityAttributeName = "priority";
|
||||
|
||||
// We need to come up with a value for the size of entries when storing a gating Task on the cache. Any value
|
||||
// greater than 0 will suffice. We choose 56 bytes as an approximation of the size of the task that we store
|
||||
// in the cache. This size got calculated as an upper bound for the size of an actual task on an x64 architecture
|
||||
// and corresponds to 24 bytes for the object header block plus the 40 bytes added by the members of the task
|
||||
// object.
|
||||
private const int PlaceholderSize = 64;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="CacheTagHelper"/>.
|
||||
/// </summary>
|
||||
/// <param name="memoryCache">The <see cref="IMemoryCache"/>.</param>
|
||||
/// <param name="factory">The factory containing the private <see cref="IMemoryCache"/> instance
|
||||
/// used by the <see cref="CacheTagHelper"/>.</param>
|
||||
/// <param name="htmlEncoder">The <see cref="HtmlEncoder"/> to use.</param>
|
||||
public CacheTagHelper(IMemoryCache memoryCache, HtmlEncoder htmlEncoder) : base(htmlEncoder)
|
||||
public CacheTagHelper(CacheTagHelperMemoryCacheFactory factory, HtmlEncoder htmlEncoder) : base(htmlEncoder)
|
||||
{
|
||||
MemoryCache = memoryCache;
|
||||
MemoryCache = factory.Cache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -93,7 +102,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
|
||||
var options = GetMemoryCacheEntryOptions();
|
||||
options.AddExpirationToken(new CancellationChangeToken(tokenSource.Token));
|
||||
|
||||
options.SetSize(PlaceholderSize);
|
||||
var tcs = new TaskCompletionSource<IHtmlContent>();
|
||||
|
||||
// The returned value is ignored, we only do this so that
|
||||
|
|
@ -116,11 +125,11 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
// such that the tokens are inherited.
|
||||
|
||||
var result = ProcessContentAsync(output);
|
||||
|
||||
entry.SetOptions(options);
|
||||
entry.Value = result;
|
||||
|
||||
content = await result;
|
||||
options.SetSize(GetSize(content));
|
||||
entry.SetOptions(options);
|
||||
|
||||
entry.Value = result;
|
||||
}
|
||||
|
||||
tcs.SetResult(content);
|
||||
|
|
@ -143,6 +152,22 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
}
|
||||
}
|
||||
|
||||
private long GetSize(IHtmlContent content)
|
||||
{
|
||||
if (content is CharBufferHtmlContent charBuffer)
|
||||
{
|
||||
// We need to multiply the size of the buffer
|
||||
// by a factor of two due to the fact that
|
||||
// characters in .NET are UTF-16 which means
|
||||
// every character uses two bytes (surrogates
|
||||
// are represented as two characters)
|
||||
return charBuffer.Buffer.Length * sizeof(char);
|
||||
}
|
||||
|
||||
Debug.Fail($"{nameof(content)} should be an {nameof(CharBufferHtmlContent)}.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Internal for unit testing
|
||||
internal MemoryCacheEntryOptions GetMemoryCacheEntryOptions()
|
||||
{
|
||||
|
|
@ -226,17 +251,19 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
_buffer = buffer;
|
||||
}
|
||||
|
||||
public PagedCharBuffer Buffer => _buffer;
|
||||
|
||||
public void WriteTo(TextWriter writer, HtmlEncoder encoder)
|
||||
{
|
||||
var length = _buffer.Length;
|
||||
var length = Buffer.Length;
|
||||
if (length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < _buffer.Pages.Count; i++)
|
||||
for (var i = 0; i < Buffer.Pages.Count; i++)
|
||||
{
|
||||
var page = _buffer.Pages[i];
|
||||
var page = Buffer.Pages[i];
|
||||
var pageLength = Math.Min(length, page.Length);
|
||||
writer.Write(page, index: 0, count: pageLength);
|
||||
length -= pageLength;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides programmatic configuration for the cache tag helper in the MVC framework.
|
||||
/// </summary>
|
||||
public class CacheTagHelperOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// The maximum total size in bytes that will be cached by the <see cref="CacheTagHelper"/>
|
||||
/// at any given time.
|
||||
/// </summary>
|
||||
public long SizeLimit { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -2,18 +2,20 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc.TagHelpers;
|
||||
using Microsoft.AspNetCore.Mvc.TagHelpers.Cache;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.AspNetCore.Mvc.TagHelpers.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
{
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for configuring Razor cache tag helpers.
|
||||
/// </summary>
|
||||
public static class TagHelperServicesExtensions
|
||||
{
|
||||
private const int DefaultCacheMaximumSizeInBytes = 100 * 1024 * 1024; // 100MB
|
||||
|
||||
/// <summary>
|
||||
/// Adds MVC cache tag helper services to the application.
|
||||
/// </summary>
|
||||
|
|
@ -26,13 +28,60 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.Services.TryAddTransient<IDistributedCacheTagHelperStorage, DistributedCacheTagHelperStorage>();
|
||||
builder.Services.TryAddTransient<IDistributedCacheTagHelperFormatter, DistributedCacheTagHelperFormatter>();
|
||||
builder.Services.TryAddSingleton<IDistributedCacheTagHelperStorage, DistributedCacheTagHelperStorage>();
|
||||
builder.Services.TryAddSingleton<IDistributedCacheTagHelperFormatter, DistributedCacheTagHelperFormatter>();
|
||||
builder.Services.TryAddSingleton<IDistributedCacheTagHelperService, DistributedCacheTagHelperService>();
|
||||
|
||||
// Required default services for cache tag helpers
|
||||
builder.Services.TryAddSingleton<IDistributedCache, MemoryDistributedCache>();
|
||||
builder.Services.TryAddSingleton<IMemoryCache, MemoryCache>();
|
||||
builder.Services.AddDistributedMemoryCache();
|
||||
builder.Services.TryAddSingleton<CacheTagHelperMemoryCacheFactory>();
|
||||
builder.AddCacheTagHelperLimits(options => options.SizeLimit = DefaultCacheMaximumSizeInBytes);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the memory size limits on the cache of the <see cref="CacheTagHelper"/>.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IMvcBuilder"/>.</param>
|
||||
/// <param name="configure">The <see cref="Action{CacheTagHelperOptions}"/>to configure the cache options.</param>
|
||||
/// <returns>The <see cref="IMvcBuilder"/>.</returns>
|
||||
public static IMvcBuilder AddCacheTagHelperLimits(this IMvcBuilder builder, Action<CacheTagHelperOptions> configure)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (configure == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(configure));
|
||||
}
|
||||
|
||||
builder.Services.Configure(configure);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the memory size limits on the cache of the <see cref="CacheTagHelper"/>.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IMvcCoreBuilder"/>.</param>
|
||||
/// <param name="configure">The <see cref="Action{CacheTagHelperOptions}"/>to configure the cache options.</param>
|
||||
/// <returns>The <see cref="IMvcCoreBuilder"/>.</returns>
|
||||
public static IMvcCoreBuilder AddCacheTagHelperLimits(this IMvcCoreBuilder builder, Action<CacheTagHelperOptions> configure)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (configure == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(configure));
|
||||
}
|
||||
|
||||
builder.Services.Configure(configure);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.TagHelpers.Internal
|
||||
{
|
||||
public class CacheTagHelperMemoryCacheFactory
|
||||
{
|
||||
public CacheTagHelperMemoryCacheFactory(IOptions<CacheTagHelperOptions> options)
|
||||
{
|
||||
Cache = new MemoryCache(new MemoryCacheOptions
|
||||
{
|
||||
SizeLimit = options.Value.SizeLimit
|
||||
});
|
||||
}
|
||||
|
||||
// For testing only.
|
||||
internal CacheTagHelperMemoryCacheFactory(IMemoryCache cache)
|
||||
{
|
||||
Cache = cache;
|
||||
}
|
||||
|
||||
public IMemoryCache Cache { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Mvc.Abstractions;
|
|||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Mvc.TagHelpers.Cache;
|
||||
using Microsoft.AspNetCore.Mvc.TagHelpers.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ViewEngines;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
|
@ -48,7 +49,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput = GetTagHelperOutput(
|
||||
attributes: new TagHelperAttributeList(),
|
||||
childContent: childContent);
|
||||
var cacheTagHelper = new CacheTagHelper(cache.Object, new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache.Object), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
Enabled = false
|
||||
|
|
@ -75,7 +76,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput = GetTagHelperOutput(
|
||||
attributes: new TagHelperAttributeList(),
|
||||
childContent: childContent);
|
||||
var cacheTagHelper = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
Enabled = true
|
||||
|
|
@ -102,7 +103,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput1 = GetTagHelperOutput(
|
||||
attributes: new TagHelperAttributeList(),
|
||||
childContent: childContent);
|
||||
var cacheTagHelper1 = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
VaryByQuery = "key1,key2",
|
||||
ViewContext = GetViewContext(),
|
||||
|
|
@ -124,7 +125,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput2 = GetTagHelperOutput(
|
||||
attributes: new TagHelperAttributeList(),
|
||||
childContent: "different-content");
|
||||
var cacheTagHelper2 = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper2 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
VaryByQuery = "key1,key2",
|
||||
ViewContext = GetViewContext(),
|
||||
|
|
@ -153,7 +154,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput1 = GetTagHelperOutput(childContent: childContent1);
|
||||
tagHelperOutput1.PreContent.Append("<cache>");
|
||||
tagHelperOutput1.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper1 = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
VaryByCookie = "cookie1,cookie2",
|
||||
ViewContext = GetViewContext(),
|
||||
|
|
@ -175,7 +176,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput2 = GetTagHelperOutput(childContent: childContent2);
|
||||
tagHelperOutput2.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput2.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper2 = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper2 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
VaryByCookie = "cookie1,cookie2",
|
||||
ViewContext = GetViewContext(),
|
||||
|
|
@ -198,7 +199,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var expiresOn = DateTimeOffset.UtcNow.AddMinutes(4);
|
||||
var cache = new MemoryCache(new MemoryCacheOptions());
|
||||
var cacheTagHelper = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ExpiresOn = expiresOn
|
||||
};
|
||||
|
|
@ -210,13 +211,58 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
Assert.Equal(expiresOn, cacheEntryOptions.AbsoluteExpiration);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ProcessAsync_SetsEntrySize_ForPlaceholderAndFinalCacheEntries()
|
||||
{
|
||||
// Arrange
|
||||
var mockCache = new Mock<IMemoryCache>();
|
||||
var tempEntry = new Mock<ICacheEntry>();
|
||||
tempEntry.SetupAllProperties();
|
||||
tempEntry.Setup(e => e.ExpirationTokens).Returns(new List<IChangeToken>());
|
||||
tempEntry.Setup(e => e.PostEvictionCallbacks).Returns(new List<PostEvictionCallbackRegistration>());
|
||||
var finalEntry = new Mock<ICacheEntry>();
|
||||
finalEntry.SetupAllProperties();
|
||||
finalEntry.Setup(e => e.ExpirationTokens).Returns(new List<IChangeToken>());
|
||||
finalEntry.Setup(e => e.PostEvictionCallbacks).Returns(new List<PostEvictionCallbackRegistration>());
|
||||
object value;
|
||||
mockCache
|
||||
.Setup(s => s.TryGetValue(It.IsAny<object>(), out value))
|
||||
.Returns(false);
|
||||
|
||||
mockCache.SetupSequence(mc => mc.CreateEntry(It.IsAny<object>()))
|
||||
.Returns(tempEntry.Object)
|
||||
.Returns(finalEntry.Object);
|
||||
|
||||
var id = "unique-id";
|
||||
var childContent1 = "original-child-content";
|
||||
var tagHelperContext1 = GetTagHelperContext(id);
|
||||
var tagHelperOutput1 = GetTagHelperOutput(childContent: childContent1);
|
||||
tagHelperOutput1.PreContent.Append("<cache>");
|
||||
tagHelperOutput1.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(mockCache.Object), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
};
|
||||
|
||||
// Act
|
||||
await cacheTagHelper1.ProcessAsync(tagHelperContext1, tagHelperOutput1);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(tagHelperOutput1.PreContent.GetContent());
|
||||
Assert.Empty(tagHelperOutput1.PostContent.GetContent());
|
||||
Assert.True(tagHelperOutput1.IsContentModified);
|
||||
Assert.Equal(childContent1, tagHelperOutput1.Content.GetContent());
|
||||
tempEntry.VerifySet(e => e.Size = 64);
|
||||
finalEntry.VerifySet(e => e.Size = childContent1.Length * 2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UpdateCacheEntryOptions_DefaultsTo30SecondsSliding_IfNoEvictionCriteriaIsProvided()
|
||||
{
|
||||
// Arrange
|
||||
var slidingExpiresIn = TimeSpan.FromSeconds(30);
|
||||
var cache = new MemoryCache(new MemoryCacheOptions());
|
||||
var cacheTagHelper = new CacheTagHelper(cache, new HtmlTestEncoder());
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder());
|
||||
|
||||
// Act
|
||||
var cacheEntryOptions = cacheTagHelper.GetMemoryCacheEntryOptions();
|
||||
|
|
@ -231,7 +277,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var expiresAfter = TimeSpan.FromSeconds(42);
|
||||
var cache = new MemoryCache(new MemoryCacheOptions());
|
||||
var cacheTagHelper = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ExpiresAfter = expiresAfter
|
||||
};
|
||||
|
|
@ -249,7 +295,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var expiresSliding = TimeSpan.FromSeconds(37);
|
||||
var cache = new MemoryCache(new MemoryCacheOptions());
|
||||
var cacheTagHelper = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ExpiresSliding = expiresSliding
|
||||
};
|
||||
|
|
@ -267,7 +313,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var priority = CacheItemPriority.High;
|
||||
var cache = new MemoryCache(new MemoryCacheOptions());
|
||||
var cacheTagHelper = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
Priority = priority
|
||||
};
|
||||
|
|
@ -294,7 +340,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput1 = GetTagHelperOutput(childContent: childContent1);
|
||||
tagHelperOutput1.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput1.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper1 = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
ExpiresAfter = TimeSpan.FromMinutes(10)
|
||||
|
|
@ -315,7 +361,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput2 = GetTagHelperOutput(childContent: childContent2);
|
||||
tagHelperOutput2.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput2.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper2 = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper2 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
ExpiresAfter = TimeSpan.FromMinutes(10)
|
||||
|
|
@ -347,7 +393,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput1 = GetTagHelperOutput(childContent: childContent1);
|
||||
tagHelperOutput1.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput1.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper1 = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
ExpiresOn = currentTime.AddMinutes(5)
|
||||
|
|
@ -369,7 +415,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput2 = GetTagHelperOutput(childContent: childContent2);
|
||||
tagHelperOutput2.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput2.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper2 = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper2 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
ExpiresOn = currentTime.AddMinutes(5)
|
||||
|
|
@ -400,7 +446,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput1 = GetTagHelperOutput(childContent: childContent1);
|
||||
tagHelperOutput1.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput1.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper1 = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
ExpiresSliding = TimeSpan.FromSeconds(30)
|
||||
|
|
@ -422,7 +468,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput2 = GetTagHelperOutput(childContent: childContent2);
|
||||
tagHelperOutput2.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput2.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper2 = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper2 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
ExpiresSliding = TimeSpan.FromSeconds(30)
|
||||
|
|
@ -469,7 +515,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
});
|
||||
tagHelperOutput.PreContent.SetContent("<cache>");
|
||||
tagHelperOutput.PostContent.SetContent("</cache>");
|
||||
var cacheTagHelper = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
};
|
||||
|
|
@ -535,13 +581,13 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
|
||||
var cacheTagHelper1 = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
Enabled = true
|
||||
};
|
||||
|
||||
var cacheTagHelper2 = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper2 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
Enabled = true
|
||||
|
|
@ -618,13 +664,13 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
return Task.FromResult<TagHelperContent>(tagHelperContent);
|
||||
});
|
||||
|
||||
var cacheTagHelper1 = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
Enabled = true
|
||||
};
|
||||
|
||||
var cacheTagHelper2 = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper2 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
Enabled = true
|
||||
|
|
@ -699,7 +745,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var tagHelperOutput3 = new TagHelperOutput("cache", new TagHelperAttributeList(), GetChildContentAsync);
|
||||
var tagHelperOutput4 = new TagHelperOutput("cache", new TagHelperAttributeList(), GetChildContentAsync);
|
||||
|
||||
var cacheTagHelper = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
Enabled = true,
|
||||
|
|
@ -762,13 +808,13 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var expected = "Hello world";
|
||||
var cache = new MemoryCache(new MemoryCacheOptions());
|
||||
var encoder = new HtmlTestEncoder();
|
||||
var cacheTagHelper1 = new CacheTagHelper(cache, encoder)
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), encoder)
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
Enabled = true
|
||||
};
|
||||
|
||||
var cacheTagHelper2 = new CacheTagHelper(cache, encoder)
|
||||
var cacheTagHelper2 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), encoder)
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
Enabled = true
|
||||
|
|
@ -808,7 +854,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var expected = new DivideByZeroException();
|
||||
var cache = new TestMemoryCache();
|
||||
var cacheTagHelper = new CacheTagHelper(cache, new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
Enabled = true
|
||||
|
|
@ -841,7 +887,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var expected = "Hello world";
|
||||
var cache = new TestMemoryCache();
|
||||
var encoder = new HtmlTestEncoder();
|
||||
var cacheTagHelper = new CacheTagHelper(cache, encoder)
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(cache), encoder)
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
Enabled = true
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Mvc.Abstractions;
|
|||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Mvc.TagHelpers.Cache;
|
||||
using Microsoft.AspNetCore.Mvc.TagHelpers.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ViewEngines;
|
||||
using Microsoft.AspNetCore.Mvc.ViewFeatures;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
|
@ -29,7 +30,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var id = Guid.NewGuid().ToString();
|
||||
var tagHelperContext = GetTagHelperContext(id);
|
||||
var cacheTagHelper = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext()
|
||||
};
|
||||
|
|
@ -49,13 +50,13 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var id = Guid.NewGuid().ToString();
|
||||
var tagHelperContext1 = GetTagHelperContext(id);
|
||||
var cacheTagHelper1 = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext()
|
||||
};
|
||||
|
||||
var tagHelperContext2 = GetTagHelperContext(id);
|
||||
var cacheTagHelper2 = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper2 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext()
|
||||
};
|
||||
|
|
@ -73,13 +74,13 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
// Arrange
|
||||
var tagHelperContext1 = GetTagHelperContext("some-id");
|
||||
var cacheTagHelper1 = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext()
|
||||
};
|
||||
|
||||
var tagHelperContext2 = GetTagHelperContext("some-other-id");
|
||||
var cacheTagHelper2 = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper2 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext()
|
||||
};
|
||||
|
|
@ -97,13 +98,13 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
// Arrange
|
||||
var tagHelperContext1 = GetTagHelperContext("some-id");
|
||||
var cacheTagHelper1 = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext()
|
||||
};
|
||||
|
||||
var tagHelperContext2 = GetTagHelperContext("some-id");
|
||||
var cacheTagHelper2 = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper2 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext()
|
||||
};
|
||||
|
|
@ -124,13 +125,13 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
// Arrange
|
||||
var tagHelperContext1 = GetTagHelperContext("some-id");
|
||||
var cacheTagHelper1 = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper1 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext()
|
||||
};
|
||||
|
||||
var tagHelperContext2 = GetTagHelperContext("some-other-id");
|
||||
var cacheTagHelper2 = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper2 = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext()
|
||||
};
|
||||
|
|
@ -177,7 +178,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
// Arrange
|
||||
var tagHelperContext = GetTagHelperContext();
|
||||
var cacheTagHelper = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
VaryBy = varyBy
|
||||
|
|
@ -206,7 +207,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
// Arrange
|
||||
var tagHelperContext = GetTagHelperContext();
|
||||
var cacheTagHelper = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
VaryByCookie = varyByCookie
|
||||
|
|
@ -232,7 +233,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
// Arrange
|
||||
var tagHelperContext = GetTagHelperContext();
|
||||
var cacheTagHelper = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
VaryByHeader = varyByHeader
|
||||
|
|
@ -260,7 +261,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
// Arrange
|
||||
var tagHelperContext = GetTagHelperContext();
|
||||
var cacheTagHelper = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
VaryByQuery = varyByQuery
|
||||
|
|
@ -286,7 +287,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
// Arrange
|
||||
var tagHelperContext = GetTagHelperContext();
|
||||
var cacheTagHelper = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
VaryByRoute = varyByRoute
|
||||
|
|
@ -308,7 +309,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var expected = "CacheTagHelper||testid||VaryByUser||";
|
||||
var tagHelperContext = GetTagHelperContext();
|
||||
var cacheTagHelper = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
VaryByUser = true
|
||||
|
|
@ -328,7 +329,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
// Arrange
|
||||
var expected = "CacheTagHelper||testid||VaryByUser||test_name";
|
||||
var tagHelperContext = GetTagHelperContext();
|
||||
var cacheTagHelper = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
VaryByUser = true
|
||||
|
|
@ -351,7 +352,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var expected = "CacheTagHelper||testid||VaryBy||custom-value||" +
|
||||
"VaryByHeader(content-type||text/html)||VaryByUser||someuser";
|
||||
var tagHelperContext = GetTagHelperContext();
|
||||
var cacheTagHelper = new CacheTagHelper(Mock.Of<IMemoryCache>(), new HtmlTestEncoder())
|
||||
var cacheTagHelper = new CacheTagHelper(new CacheTagHelperMemoryCacheFactory(Mock.Of<IMemoryCache>()), new HtmlTestEncoder())
|
||||
{
|
||||
ViewContext = GetViewContext(),
|
||||
VaryByUser = true,
|
||||
|
|
|
|||
Loading…
Reference in New Issue