Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

Commit 6af555a

Browse files
author
N. Taylor Mullen
committed
Removed the TypeActivator from TagHelper creation.
- We now rely on Activator.CreateInstance to instantiate TagHelpers. - Added test to validate throwing. - Removed existing tests that expected the constructor injection behavior. #1303
1 parent ce49b77 commit 6af555a

File tree

4 files changed

+59
-70
lines changed

4 files changed

+59
-70
lines changed

src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Microsoft.AspNet.Mvc.Razor/RazorPage.cs

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public abstract class RazorPage : IRazorPage
2525
private readonly Stack<TextWriter> _writerScopes;
2626
private TextWriter _originalWriter;
2727
private IUrlHelper _urlHelper;
28-
private ITypeActivator _typeActivator;
2928
private ITagHelperActivator _tagHelperActivator;
3029
private bool _renderedBody;
3130

@@ -114,19 +113,6 @@ public dynamic ViewBag
114113
/// <inheritdoc />
115114
public abstract Task ExecuteAsync();
116115

117-
private ITypeActivator TypeActivator
118-
{
119-
get
120-
{
121-
if(_typeActivator == null)
122-
{
123-
_typeActivator = ViewContext.HttpContext.RequestServices.GetService<ITypeActivator>();
124-
}
125-
126-
return _typeActivator;
127-
}
128-
}
129-
130116
private ITagHelperActivator TagHelperActivator
131117
{
132118
get
@@ -139,19 +125,30 @@ private ITagHelperActivator TagHelperActivator
139125
return _tagHelperActivator;
140126
}
141127
}
142-
143128
/// <summary>
144129
/// Creates and activates a <see cref="ITagHelper"/>.
145130
/// </summary>
146131
/// <typeparam name="TTagHelper">A <see cref="ITagHelper"/> type.</typeparam>
147132
/// <returns>The activated <see cref="ITagHelper"/>.</returns>
148133
/// <remarks>
149-
/// If the <see cref= "ITagHelper" /> implements <see cref="ICanHasViewContext"/> the
150-
/// <see cref="ICanHasViewContext.Contextualize(ViewContext)"/> method is called with <see cref="ViewContext"/>.
134+
/// <typeparamref name="TTagHelper"/> must have a parameterless constructor.
151135
/// </remarks>
152136
public TTagHelper CreateTagHelper<TTagHelper>() where TTagHelper : ITagHelper
153137
{
154-
var tagHelper = TypeActivator.CreateInstance<TTagHelper>(ViewContext.HttpContext.RequestServices);
138+
TTagHelper tagHelper;
139+
140+
try
141+
{
142+
tagHelper = Activator.CreateInstance<TTagHelper>();
143+
}
144+
catch
145+
{
146+
// Activator.CreateInstance will throw a MissingMethodException if there is no parameterless
147+
// constructor. Rethrow a more informative error.
148+
throw new MissingMethodException(
149+
Resources.FormatCreateTagHelper_TagHelpersMustHaveParameterlessConstructors(
150+
typeof(TTagHelper).FullName));
151+
}
155152

156153
TagHelperActivator.Activate(tagHelper, ViewContext);
157154

src/Microsoft.AspNet.Mvc.Razor/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,4 +186,7 @@
186186
<data name="View_MethodCannotBeCalled" xml:space="preserve">
187187
<value>The method '{0}' cannot be invoked by this view.</value>
188188
</data>
189+
<data name="CreateTagHelper_TagHelpersMustHaveParameterlessConstructors" xml:space="preserve">
190+
<value>Tag helper `{0}` must have a public paramterless constructor.</value>
191+
</data>
189192
</root>

test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageCreateTagHelperTest.cs

Lines changed: 25 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
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 System.Globalization;
56
using System.IO;
67
using System.Threading.Tasks;
78
using Microsoft.AspNet.Http;
@@ -18,56 +19,48 @@ namespace Microsoft.AspNet.Mvc.Razor
1819
public class RazorPageCreateTagHelperTest
1920
{
2021
[Fact]
21-
public void CreateTagHelper_CreatesProvidedTagHelperType()
22-
{
23-
// Arrange
24-
var instance = CreateTestRazorPage();
25-
26-
// Act
27-
var tagHelper = instance.CreateTagHelper<NoServiceTagHelper>();
28-
29-
// Assert
30-
Assert.NotNull(tagHelper);
31-
}
32-
33-
[Fact]
34-
public void CreateTagHelper_ActivatesProvidedTagHelperType_Constructor()
22+
public void CreateTagHelper_ThrowsIfNoParameterlessConstructor()
3523
{
3624
// Arrange
3725
var instance = CreateTestRazorPage();
26+
var expectedErrorMessage = string.Format(
27+
CultureInfo.InvariantCulture,
28+
"Tag helper `{0}` must have a public paramterless constructor.",
29+
typeof(NoParameterlessConstructor).FullName);
3830

39-
// Act
40-
var tagHelper = instance.CreateTagHelper<ConstructorServiceTagHelper>();
31+
// Act & Assert
32+
var ex = Assert.Throws<MissingMethodException>(() =>
33+
{
34+
instance.CreateTagHelper<NoParameterlessConstructor>();
35+
});
4136

42-
// Assert
43-
Assert.NotNull(tagHelper.PassedInService);
37+
Assert.Equal(expectedErrorMessage, ex.Message);
4438
}
4539

4640
[Fact]
47-
public void CreateTagHelper_ActivatesProvidedTagHelperType_Property()
41+
public void CreateTagHelper_CreatesProvidedTagHelperType()
4842
{
4943
// Arrange
5044
var instance = CreateTestRazorPage();
5145

5246
// Act
53-
var tagHelper = instance.CreateTagHelper<ActivateAttributeServiceTagHelper>();
47+
var tagHelper = instance.CreateTagHelper<NoServiceTagHelper>();
5448

5549
// Assert
56-
Assert.NotNull(tagHelper.ActivatedService);
50+
Assert.NotNull(tagHelper);
5751
}
5852

5953
[Fact]
60-
public void CreateTagHelper_ActivatesProvidedTagHelperType_PropertyAndConstructor()
54+
public void CreateTagHelper_ActivatesProvidedTagHelperType()
6155
{
6256
// Arrange
6357
var instance = CreateTestRazorPage();
6458

6559
// Act
66-
var tagHelper = instance.CreateTagHelper<AttributeConstructorServiceTagHelper>();
60+
var tagHelper = instance.CreateTagHelper<ServiceTagHelper>();
6761

6862
// Assert
6963
Assert.NotNull(tagHelper.ActivatedService);
70-
Assert.NotNull(tagHelper.PassedInService);
7164
}
7265

7366
[Fact]
@@ -94,7 +87,7 @@ public void CreateTagHelper_ProvidesTagHelperTypeWithViewContextAndActivates()
9487

9588
// Assert
9689
Assert.NotNull(tagHelper.ViewContext);
97-
Assert.NotNull(tagHelper.PassedInService);
90+
Assert.NotNull(tagHelper.ActivatedService);
9891
}
9992

10093
private static TestRazorPage CreateTestRazorPage()
@@ -138,33 +131,10 @@ private class NoServiceTagHelper : TagHelper
138131
{
139132
}
140133

141-
private class ConstructorServiceTagHelper : TagHelper
142-
{
143-
public MyService PassedInService { get; set; }
144-
145-
public ConstructorServiceTagHelper(MyService service)
146-
{
147-
PassedInService = service;
148-
}
149-
}
150-
151-
private class ActivateAttributeServiceTagHelper : TagHelper
152-
{
153-
[Activate]
154-
public MyService ActivatedService { get; set; }
155-
}
156-
157-
private class AttributeConstructorServiceTagHelper : TagHelper
134+
private class ServiceTagHelper : TagHelper
158135
{
159136
[Activate]
160137
public MyService ActivatedService { get; set; }
161-
162-
public MyService PassedInService { get; set; }
163-
164-
public AttributeConstructorServiceTagHelper(MyService service)
165-
{
166-
PassedInService = service;
167-
}
168138
}
169139

170140
private class ViewContextTagHelper : TagHelper
@@ -175,11 +145,14 @@ private class ViewContextTagHelper : TagHelper
175145

176146
private class ViewContextServiceTagHelper : ViewContextTagHelper
177147
{
178-
public MyService PassedInService { get; set; }
148+
[Activate]
149+
public MyService ActivatedService { get; set; }
150+
}
179151

180-
public ViewContextServiceTagHelper(MyService service)
152+
private class NoParameterlessConstructor : TagHelper
153+
{
154+
public NoParameterlessConstructor(string a)
181155
{
182-
PassedInService = service;
183156
}
184157
}
185158

0 commit comments

Comments
 (0)