From e8327eeec76afcb4156e95763e580df3693f4d8e Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Thu, 12 Nov 2015 17:11:59 -0800 Subject: [PATCH] Lazily initialize `TagHelperOutput`s `Content` properties. - Added backing fields to each of the content properties and added null propagation checks throughout the class. #358 --- .../TagHelpers/TagHelperOutput.cs | 105 +++++++++++++++--- 1 file changed, 88 insertions(+), 17 deletions(-) diff --git a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperOutput.cs b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperOutput.cs index db9614af62..e288bc4c9a 100644 --- a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperOutput.cs +++ b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperOutput.cs @@ -15,6 +15,12 @@ namespace Microsoft.AspNet.Razor.TagHelpers public class TagHelperOutput : IHtmlContent { private readonly Func> _getChildContentAsync; + private TagHelperContent _preElement; + private TagHelperContent _preContent; + private TagHelperContent _content; + private TagHelperContent _postContent; + private TagHelperContent _postElement; + private bool _wasSuppressOutputCalled; // Internal for testing internal TagHelperOutput(string tagName) @@ -64,32 +70,96 @@ namespace Microsoft.AspNet.Razor.TagHelpers /// Content that precedes the HTML element. /// /// Value is rendered before the HTML element. - public TagHelperContent PreElement { get; } = new DefaultTagHelperContent(); + public TagHelperContent PreElement + { + get + { + if (_preElement == null) + { + _preElement = new DefaultTagHelperContent(); + } + + return _preElement; + } + } /// /// The HTML element's pre content. /// /// Value is prepended to the 's final output. - public TagHelperContent PreContent { get; } = new DefaultTagHelperContent(); + public TagHelperContent PreContent + { + get + { + if (_preContent == null) + { + _preContent = new DefaultTagHelperContent(); + } + + return _preContent; + } + } /// - /// The HTML element's main content. + /// Get or set the HTML element's main content. /// /// Value occurs in the 's final output after and /// before - public TagHelperContent Content { get; } = new DefaultTagHelperContent(); + public TagHelperContent Content + { + get + { + if (_content == null) + { + _content = new DefaultTagHelperContent(); + } + + return _content; + } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + _content = value; + } + } /// /// The HTML element's post content. /// /// Value is appended to the 's final output. - public TagHelperContent PostContent { get; } = new DefaultTagHelperContent(); + public TagHelperContent PostContent + { + get + { + if (_postContent == null) + { + _postContent = new DefaultTagHelperContent(); + } + + return _postContent; + } + } /// /// Content that follows the HTML element. /// /// Value is rendered after the HTML element. - public TagHelperContent PostElement { get; } = new DefaultTagHelperContent(); + public TagHelperContent PostElement + { + get + { + if (_postElement == null) + { + _postElement = new DefaultTagHelperContent(); + } + + return _postElement; + } + } /// /// true if has been set, false otherwise. @@ -98,7 +168,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers { get { - return Content.IsModified; + return _wasSuppressOutputCalled || _content?.IsModified == true; } } @@ -127,11 +197,12 @@ namespace Microsoft.AspNet.Razor.TagHelpers public void SuppressOutput() { TagName = null; - PreElement.Clear(); - PreContent.Clear(); - Content.Clear(); - PostContent.Clear(); - PostElement.Clear(); + _wasSuppressOutputCalled = true; + _preElement?.Clear(); + _preContent?.Clear(); + _content?.Clear(); + _postContent?.Clear(); + _postElement?.Clear(); } /// @@ -163,7 +234,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers throw new ArgumentNullException(nameof(writer)); } - PreElement.WriteTo(writer, encoder); + _preElement?.WriteTo(writer, encoder); var isTagNameNullOrWhitespace = string.IsNullOrWhiteSpace(TagName); @@ -218,11 +289,11 @@ namespace Microsoft.AspNet.Razor.TagHelpers if (isTagNameNullOrWhitespace || TagMode == TagMode.StartTagAndEndTag) { - PreContent.WriteTo(writer, encoder); + _preContent?.WriteTo(writer, encoder); - Content.WriteTo(writer, encoder); + _content?.WriteTo(writer, encoder); - PostContent.WriteTo(writer, encoder); + _postContent?.WriteTo(writer, encoder); } if (!isTagNameNullOrWhitespace && TagMode == TagMode.StartTagAndEndTag) @@ -232,7 +303,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers writer.Write(">"); } - PostElement.WriteTo(writer, encoder); + _postElement?.WriteTo(writer, encoder); } } }