Skip to content

Commit 27610b0

Browse files
authored
Use generics trick to cache tag helper instances (#28208)
- Remove the use of ITypeActivatorCache
1 parent 2c175f7 commit 27610b0

File tree

4 files changed

+14
-30
lines changed

4 files changed

+14
-30
lines changed

src/Mvc/Mvc.Razor/src/Infrastructure/DefaultTagHelperActivator.cs

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5-
using Microsoft.AspNetCore.Mvc.Infrastructure;
65
using Microsoft.AspNetCore.Mvc.Rendering;
76
using Microsoft.AspNetCore.Razor.TagHelpers;
7+
using Microsoft.Extensions.DependencyInjection;
88

99
namespace Microsoft.AspNetCore.Mvc.Razor.Infrastructure
1010
{
@@ -13,22 +13,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Infrastructure
1313
/// </summary>
1414
internal class DefaultTagHelperActivator : ITagHelperActivator
1515
{
16-
private readonly ITypeActivatorCache _typeActivatorCache;
17-
18-
/// <summary>
19-
/// Instantiates a new <see cref="DefaultTagHelperActivator"/> instance.
20-
/// </summary>
21-
/// <param name="typeActivatorCache">The <see cref="ITypeActivatorCache"/>.</param>
22-
public DefaultTagHelperActivator(ITypeActivatorCache typeActivatorCache)
23-
{
24-
if (typeActivatorCache == null)
25-
{
26-
throw new ArgumentNullException(nameof(typeActivatorCache));
27-
}
28-
29-
_typeActivatorCache = typeActivatorCache;
30-
}
31-
3216
/// <inheritdoc />
3317
public TTagHelper Create<TTagHelper>(ViewContext context)
3418
where TTagHelper : ITagHelper
@@ -38,9 +22,14 @@ public TTagHelper Create<TTagHelper>(ViewContext context)
3822
throw new ArgumentNullException(nameof(context));
3923
}
4024

41-
return _typeActivatorCache.CreateInstance<TTagHelper>(
42-
context.HttpContext.RequestServices,
43-
typeof(TTagHelper));
25+
return Cache<TTagHelper>.Create(context.HttpContext.RequestServices);
26+
}
27+
28+
private static class Cache<TTagHelper>
29+
{
30+
private static readonly ObjectFactory _objectFactory = ActivatorUtilities.CreateFactory(typeof(TTagHelper), Type.EmptyTypes);
31+
32+
public static TTagHelper Create(IServiceProvider serviceProvider) => (TTagHelper)_objectFactory(serviceProvider, arguments: null);
4433
}
4534
}
4635
}

src/Mvc/Mvc.Razor/test/Infrastructure/DefaultTagHelperActivatorTest.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.IO;
55
using Microsoft.AspNetCore.Http;
66
using Microsoft.AspNetCore.Mvc.Abstractions;
7-
using Microsoft.AspNetCore.Mvc.Infrastructure;
87
using Microsoft.AspNetCore.Mvc.ModelBinding;
98
using Microsoft.AspNetCore.Mvc.Rendering;
109
using Microsoft.AspNetCore.Mvc.ViewEngines;
@@ -30,7 +29,7 @@ public void CreateTagHelper_InitializesTagHelpers()
3029
var viewContext = MakeViewContext(httpContext);
3130
var viewDataValue = new object();
3231
viewContext.ViewData.Add("TestData", viewDataValue);
33-
var activator = new DefaultTagHelperActivator(new TypeActivatorCache());
32+
var activator = new DefaultTagHelperActivator();
3433

3534
// Act
3635
var helper = activator.Create<TestTagHelper>(viewContext);

src/Mvc/Mvc.Razor/test/RazorPageCreateTagHelperTest.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,17 +82,14 @@ private static TestRazorPage CreateTestRazorPage()
8282
modelExpressionProvider);
8383

8484
var serviceProvider = new Mock<IServiceProvider>();
85-
var typeActivator = new TypeActivatorCache();
86-
var tagHelperActivator = new DefaultTagHelperActivator(typeActivator);
85+
var tagHelperActivator = new DefaultTagHelperActivator();
8786
var myService = new MyService();
8887
serviceProvider.Setup(mock => mock.GetService(typeof(MyService)))
8988
.Returns(myService);
9089
serviceProvider.Setup(mock => mock.GetService(typeof(ITagHelperFactory)))
9190
.Returns(new DefaultTagHelperFactory(tagHelperActivator));
9291
serviceProvider.Setup(mock => mock.GetService(typeof(ITagHelperActivator)))
9392
.Returns(tagHelperActivator);
94-
serviceProvider.Setup(mock => mock.GetService(typeof(ITypeActivatorCache)))
95-
.Returns(typeActivator);
9693
serviceProvider.Setup(mock => mock.GetService(It.Is<Type>(serviceType =>
9794
serviceType.IsGenericType && serviceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))))
9895
.Returns<Type>(serviceType =>

src/Mvc/Mvc.TagHelpers/test/DefaultTagHelperActivatorTest.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System.Text.Encodings.Web;
55
using Microsoft.AspNetCore.Hosting;
66
using Microsoft.AspNetCore.Http;
7-
using Microsoft.AspNetCore.Mvc.Infrastructure;
87
using Microsoft.AspNetCore.Mvc.Razor.Infrastructure;
98
using Microsoft.AspNetCore.Mvc.Rendering;
109
using Microsoft.AspNetCore.Mvc.Routing;
@@ -29,7 +28,7 @@ public class DefaultTagHelperActivatorTest
2928
public void ScriptTagHelper_DoesNotUseMemoryCacheInstanceFromDI()
3029
{
3130
// Arrange
32-
var activator = new DefaultTagHelperActivator(new TypeActivatorCache());
31+
var activator = new DefaultTagHelperActivator();
3332
var viewContext = CreateViewContext();
3433

3534
var scriptTagHelper = activator.Create<ScriptTagHelper>(viewContext);
@@ -43,7 +42,7 @@ public void ScriptTagHelper_DoesNotUseMemoryCacheInstanceFromDI()
4342
public void LinkTagHelper_DoesNotUseMemoryCacheInstanceFromDI()
4443
{
4544
// Arrange
46-
var activator = new DefaultTagHelperActivator(new TypeActivatorCache());
45+
var activator = new DefaultTagHelperActivator();
4746
var viewContext = CreateViewContext();
4847

4948
var linkTagHelper = activator.Create<LinkTagHelper>(viewContext);

0 commit comments

Comments
 (0)