diff --git a/src/Microsoft.AspNet.Mvc.Razor/Buffer/IRazorBufferScope.cs b/src/Microsoft.AspNet.Mvc.Razor/Buffer/IRazorBufferScope.cs
deleted file mode 100644
index 794ebfb00e..0000000000
--- a/src/Microsoft.AspNet.Mvc.Razor/Buffer/IRazorBufferScope.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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.AspNet.Mvc.Razor.Buffer
-{
- ///
- /// Creates and manages the lifetime of instances.
- ///
- public interface IRazorBufferScope
- {
- ///
- /// Gets a .
- ///
- /// The .
- RazorBufferSegment GetSegment();
- }
-}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Buffer/MemoryPoolRazorBufferScope.cs b/src/Microsoft.AspNet.Mvc.Razor/Buffer/MemoryPoolRazorBufferScope.cs
deleted file mode 100644
index 1c8cbe3239..0000000000
--- a/src/Microsoft.AspNet.Mvc.Razor/Buffer/MemoryPoolRazorBufferScope.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-// 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 System;
-using System.Collections.Generic;
-using Microsoft.Extensions.MemoryPool;
-
-namespace Microsoft.AspNet.Mvc.Razor.Buffer
-{
- ///
- /// A that uses pooled memory.
- ///
- public class MemoryPoolRazorBufferScope : IRazorBufferScope, IDisposable
- {
- private const int SegmentSize = 1024;
- private readonly IArraySegmentPool _pool;
- private List> _leased;
- private bool _disposed;
-
- ///
- /// Initializes a new instance of .
- ///
- /// The for creating
- /// instances.
- public MemoryPoolRazorBufferScope(IArraySegmentPool pool)
- {
- _pool = pool;
- }
-
- ///
- public RazorBufferSegment GetSegment()
- {
- if (_disposed)
- {
- throw new ObjectDisposedException(typeof(MemoryPoolRazorBufferScope).FullName);
- }
-
- if (_leased == null)
- {
- _leased = new List>(1);
- }
-
- LeasedArraySegment segment = null;
-
- try
- {
- segment = _pool.Lease(SegmentSize);
- _leased.Add(segment);
- }
- catch when (segment != null)
- {
- segment.Owner.Return(segment);
- throw;
- }
-
- return new RazorBufferSegment(segment.Data);
- }
-
- ///
- public void Dispose()
- {
- if (!_disposed)
- {
- _disposed = true;
-
- if (_leased == null)
- {
- return;
- }
-
- for (var i = 0; i < _leased.Count; i++)
- {
- var segment = _leased[i];
- Array.Clear(segment.Data.Array, segment.Data.Offset, segment.Data.Count);
- segment.Owner.Return(segment);
- }
-
- _leased.Clear();
- }
- }
- }
-}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Buffer/RazorBufferSegment.cs b/src/Microsoft.AspNet.Mvc.Razor/Buffer/RazorBufferSegment.cs
deleted file mode 100644
index 2a61592124..0000000000
--- a/src/Microsoft.AspNet.Mvc.Razor/Buffer/RazorBufferSegment.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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 System;
-
-namespace Microsoft.AspNet.Mvc.Razor.Buffer
-{
- ///
- /// Encapsulates a .
- ///
- public struct RazorBufferSegment
- {
- ///
- /// Initializes a new instance of .
- ///
- /// The to encapsulate.
- public RazorBufferSegment(ArraySegment data)
- {
- Data = data;
- }
-
- ///
- /// Gets the .
- ///
- public ArraySegment Data { get; }
- }
-}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs
index dc6e2d04a3..8a49814885 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs
@@ -6,7 +6,6 @@ using System.Linq;
using System.Reflection;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Razor;
-using Microsoft.AspNet.Mvc.Razor.Buffer;
using Microsoft.AspNet.Mvc.Razor.Compilation;
using Microsoft.AspNet.Mvc.Razor.Directives;
using Microsoft.AspNet.Mvc.Razor.Internal;
@@ -160,9 +159,6 @@ namespace Microsoft.Extensions.DependencyInjection
// Consumed by the Cache tag helper to cache results across the lifetime of the application.
services.TryAddSingleton();
- services.TryAddSingleton, DefaultArraySegmentPool>();
- services.TryAddScoped();
-
if (PlatformServices.Default?.AssemblyLoadContextAccessor != null)
{
services.TryAddSingleton(PlatformServices.Default.AssemblyLoadContextAccessor);
diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorPage.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorPage.cs
index 0970302dd6..2dd18edca1 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/RazorPage.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/RazorPage.cs
@@ -17,6 +17,7 @@ using Microsoft.AspNet.Mvc.Razor.Internal;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.Routing;
using Microsoft.AspNet.Mvc.ViewFeatures;
+using Microsoft.AspNet.Mvc.ViewFeatures.Buffer;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using Microsoft.AspNet.Razor.TagHelpers;
using Microsoft.Extensions.DependencyInjection;
@@ -37,12 +38,12 @@ namespace Microsoft.AspNet.Mvc.Razor
private bool _renderedBody;
private AttributeInfo _attributeInfo;
private TagHelperAttributeInfo _tagHelperAttributeInfo;
- private StringCollectionTextWriter _valueBuffer;
+ private HtmlContentWrapperTextWriter _valueBuffer;
+ private IViewBufferScope _bufferScope;
public RazorPage()
{
SectionWriters = new Dictionary(StringComparer.OrdinalIgnoreCase);
-
_writerScopes = new Stack();
}
@@ -148,6 +149,20 @@ namespace Microsoft.AspNet.Mvc.Razor
}
}
+ private IViewBufferScope BufferScope
+ {
+ get
+ {
+ if (_bufferScope == null)
+ {
+ var services = ViewContext.HttpContext.RequestServices;
+ _bufferScope = services.GetRequiredService();
+ }
+
+ return _bufferScope;
+ }
+ }
+
///
/// Format an error message about using an indexer when the tag helper property is null.
///
@@ -194,7 +209,8 @@ namespace Microsoft.AspNet.Mvc.Razor
///
public void StartTagHelperWritingScope()
{
- StartTagHelperWritingScope(new StringCollectionTextWriter(Output.Encoding));
+ var buffer = new ViewBuffer(BufferScope, Path);
+ StartTagHelperWritingScope(new HtmlContentWrapperTextWriter(buffer, Output.Encoding));
}
///
@@ -221,7 +237,7 @@ namespace Microsoft.AspNet.Mvc.Razor
// from HTML helpers) is redirected.
ViewContext.Writer = writer;
- _writerScopes.Push(ViewContext.Writer);
+ _writerScopes.Push(writer);
}
///
@@ -258,10 +274,10 @@ namespace Microsoft.AspNet.Mvc.Razor
}
else
{
- var stringCollectionTextWriter = writer as StringCollectionTextWriter;
- if (stringCollectionTextWriter != null)
+ var htmlContentTextWriter = writer as HtmlContentWrapperTextWriter;
+ if (htmlContentTextWriter != null)
{
- tagHelperContent.Append(stringCollectionTextWriter.Content);
+ tagHelperContent.Append(htmlContentTextWriter.ContentBuilder);
}
else
{
@@ -586,7 +602,8 @@ namespace Microsoft.AspNet.Mvc.Razor
{
if (_valueBuffer == null)
{
- _valueBuffer = new StringCollectionTextWriter(Output.Encoding);
+ var buffer = new ViewBuffer(BufferScope, Path);
+ _valueBuffer = new HtmlContentWrapperTextWriter(buffer, Output.Encoding);
}
if (!string.IsNullOrEmpty(prefix))
@@ -604,7 +621,7 @@ namespace Microsoft.AspNet.Mvc.Razor
{
executionContext.AddHtmlAttribute(
_tagHelperAttributeInfo.Name,
- _valueBuffer?.Content ?? HtmlString.Empty);
+ (IHtmlContent)_valueBuffer?.ContentBuilder ?? HtmlString.Empty);
_valueBuffer = null;
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorTextWriter.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorTextWriter.cs
index bbb40f4011..3ca7aef74a 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/RazorTextWriter.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/RazorTextWriter.cs
@@ -7,6 +7,7 @@ using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNet.Html;
+using Microsoft.AspNet.Mvc.ViewFeatures;
namespace Microsoft.AspNet.Mvc.Razor
{
diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs
index 3b724dbc1f..d2394a2a0d 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs
@@ -7,9 +7,9 @@ using System.Diagnostics;
using System.Linq;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
-using Microsoft.AspNet.Mvc.Razor.Buffer;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewEngines;
+using Microsoft.AspNet.Mvc.ViewFeatures.Buffer;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNet.Mvc.Razor
@@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Mvc.Razor
private readonly IRazorViewEngine _viewEngine;
private readonly IRazorPageActivator _pageActivator;
private readonly HtmlEncoder _htmlEncoder;
- private IRazorBufferScope _bufferScope;
+ private IViewBufferScope _bufferScope;
///
/// Initializes a new instance of
@@ -97,7 +97,7 @@ namespace Microsoft.AspNet.Mvc.Razor
throw new ArgumentNullException(nameof(context));
}
- _bufferScope = context.HttpContext.RequestServices.GetRequiredService();
+ _bufferScope = context.HttpContext.RequestServices.GetRequiredService();
var bodyWriter = await RenderPageAsync(RazorPage, context, invokeViewStarts: true);
await RenderLayoutAsync(context, bodyWriter);
}
@@ -108,7 +108,7 @@ namespace Microsoft.AspNet.Mvc.Razor
bool invokeViewStarts)
{
Debug.Assert(_bufferScope != null);
- var buffer = new RazorBuffer(_bufferScope, page.Path);
+ var buffer = new ViewBuffer(_bufferScope, page.Path);
var razorTextWriter = new RazorTextWriter(context.Writer, buffer, _htmlEncoder);
// The writer for the body is passed through the ViewContext, allowing things like HtmlHelpers
diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/IViewBufferScope.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/IViewBufferScope.cs
new file mode 100644
index 0000000000..d8ad81044d
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/IViewBufferScope.cs
@@ -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.AspNet.Mvc.ViewFeatures.Buffer
+{
+ ///
+ /// Creates and manages the lifetime of instances.
+ ///
+ public interface IViewBufferScope
+ {
+ ///
+ /// Gets a .
+ ///
+ /// The .
+ ViewBufferValue[] GetSegment();
+ }
+}
diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/MemoryPoolViewBufferScope.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/MemoryPoolViewBufferScope.cs
new file mode 100644
index 0000000000..084a2bc1cf
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/MemoryPoolViewBufferScope.cs
@@ -0,0 +1,80 @@
+// 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 System;
+using System.Buffers;
+using System.Collections.Generic;
+
+namespace Microsoft.AspNet.Mvc.ViewFeatures.Buffer
+{
+ ///
+ /// A that uses pooled memory.
+ ///
+ public class MemoryPoolViewBufferScope : IViewBufferScope, IDisposable
+ {
+ public static readonly int SegmentSize = 512;
+ private readonly ArrayPool _pool;
+ private List _leased;
+ private bool _disposed;
+
+ ///
+ /// Initializes a new instance of .
+ ///
+ /// The for creating
+ /// instances.
+ public MemoryPoolViewBufferScope(ArrayPool pool)
+ {
+ _pool = pool;
+ }
+
+ ///
+ public ViewBufferValue[] GetSegment()
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(typeof(MemoryPoolViewBufferScope).FullName);
+ }
+
+ if (_leased == null)
+ {
+ _leased = new List(1);
+ }
+
+ ViewBufferValue[] segment = null;
+
+ try
+ {
+ segment = _pool.Rent(SegmentSize);
+ _leased.Add(segment);
+ }
+ catch when (segment != null)
+ {
+ _pool.Return(segment);
+ throw;
+ }
+
+ return segment;
+ }
+
+ ///
+ public void Dispose()
+ {
+ if (!_disposed)
+ {
+ _disposed = true;
+
+ if (_leased == null)
+ {
+ return;
+ }
+
+ for (var i = 0; i < _leased.Count; i++)
+ {
+ _pool.Return(_leased[i]);
+ }
+
+ _leased.Clear();
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Buffer/RazorBuffer.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/ViewBuffer.cs
similarity index 76%
rename from src/Microsoft.AspNet.Mvc.Razor/Buffer/RazorBuffer.cs
rename to src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/ViewBuffer.cs
index 906479aeef..9f94fafaa5 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Buffer/RazorBuffer.cs
+++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/ViewBuffer.cs
@@ -9,23 +9,23 @@ using System.Text.Encodings.Web;
using Microsoft.AspNet.Html;
using Microsoft.AspNet.Mvc.Rendering;
-namespace Microsoft.AspNet.Mvc.Razor.Buffer
+namespace Microsoft.AspNet.Mvc.ViewFeatures.Buffer
{
///
- /// An that is backed by a buffer provided by .
+ /// An that is backed by a buffer provided by .
///
[DebuggerDisplay("{DebuggerToString()}")]
- public class RazorBuffer : IHtmlContentBuilder
+ public class ViewBuffer : IHtmlContentBuilder
{
- private readonly IRazorBufferScope _bufferScope;
+ private readonly IViewBufferScope _bufferScope;
private readonly string _name;
///
- /// Initializes a new instance of .
+ /// Initializes a new instance of .
///
- /// The .
+ /// The .
/// A name to identify this instance.
- public RazorBuffer(IRazorBufferScope bufferScope, string name)
+ public ViewBuffer(IViewBufferScope bufferScope, string name)
{
if (bufferScope == null)
{
@@ -39,7 +39,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Buffer
///
/// Gets the backing buffer.
///
- public IList BufferSegments { get; private set; }
+ public IList BufferSegments { get; private set; }
///
/// Gets the count of entries in the last element of .
@@ -54,7 +54,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Buffer
return this;
}
- AppendValue(new RazorValue(unencoded));
+ AppendValue(new ViewBufferValue(unencoded));
return this;
}
@@ -66,7 +66,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Buffer
return this;
}
- AppendValue(new RazorValue(content));
+ AppendValue(new ViewBufferValue(content));
return this;
}
@@ -79,23 +79,23 @@ namespace Microsoft.AspNet.Mvc.Razor.Buffer
}
var value = new HtmlString(encoded);
- AppendValue(new RazorValue(value));
+ AppendValue(new ViewBufferValue(value));
return this;
}
- private void AppendValue(RazorValue value)
+ private void AppendValue(ViewBufferValue value)
{
- RazorBufferSegment segment;
+ ViewBufferValue[] segment;
if (BufferSegments == null)
{
- BufferSegments = new List(1);
+ BufferSegments = new List(1);
segment = _bufferScope.GetSegment();
BufferSegments.Add(segment);
}
else
{
segment = BufferSegments[BufferSegments.Count - 1];
- if (CurrentCount == segment.Data.Count)
+ if (CurrentCount == segment.Length)
{
segment = _bufferScope.GetSegment();
BufferSegments.Add(segment);
@@ -103,7 +103,7 @@ namespace Microsoft.AspNet.Mvc.Razor.Buffer
}
}
- segment.Data.Array[segment.Data.Offset + CurrentCount] = value;
+ segment[CurrentCount] = value;
CurrentCount++;
}
@@ -137,11 +137,11 @@ namespace Microsoft.AspNet.Mvc.Razor.Buffer
for (var i = 0; i < BufferSegments.Count; i++)
{
var segment = BufferSegments[i];
- var count = i == BufferSegments.Count - 1 ? CurrentCount : segment.Data.Count;
+ var count = i == BufferSegments.Count - 1 ? CurrentCount : segment.Length;
for (var j = 0; j < count; j++)
{
- var value = segment.Data.Array[segment.Data.Offset + j];
+ var value = segment[j];
value.WriteTo(writer, encoder);
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Buffer/RazorValue.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/ViewBufferValue.cs
similarity index 81%
rename from src/Microsoft.AspNet.Mvc.Razor/Buffer/RazorValue.cs
rename to src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/ViewBufferValue.cs
index 0807575985..7a29077b2c 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Buffer/RazorValue.cs
+++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/ViewBufferValue.cs
@@ -6,27 +6,27 @@ using System.IO;
using System.Text.Encodings.Web;
using Microsoft.AspNet.Html;
-namespace Microsoft.AspNet.Mvc.Razor.Buffer
+namespace Microsoft.AspNet.Mvc.ViewFeatures.Buffer
{
///
/// Encapsulates a string or value.
///
- public struct RazorValue
+ public struct ViewBufferValue
{
///
- /// Initializes a new instance of with a string value.
+ /// Initializes a new instance of with a string value.
///
/// The value.
- public RazorValue(string value)
+ public ViewBufferValue(string value)
{
Value = value;
}
///
- /// Initializes a new instance of with a value.
+ /// Initializes a new instance of with a value.
///
/// The .
- public RazorValue(IHtmlContent content)
+ public ViewBufferValue(IHtmlContent content)
{
Value = content;
}
diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcCoreBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcCoreBuilderExtensions.cs
index db4ad3ed7b..a75acecf89 100644
--- a/src/Microsoft.AspNet.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcCoreBuilderExtensions.cs
+++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/DependencyInjection/MvcViewFeaturesMvcCoreBuilderExtensions.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Buffers;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Controllers;
using Microsoft.AspNet.Mvc.Formatters;
@@ -9,8 +10,10 @@ using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewComponents;
using Microsoft.AspNet.Mvc.ViewEngines;
using Microsoft.AspNet.Mvc.ViewFeatures;
+using Microsoft.AspNet.Mvc.ViewFeatures.Buffer;
using Microsoft.AspNet.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.MemoryPool;
using Microsoft.Extensions.OptionsModel;
namespace Microsoft.Extensions.DependencyInjection
@@ -136,6 +139,9 @@ namespace Microsoft.Extensions.DependencyInjection
// These are stateless so their lifetime isn't really important.
services.TryAddSingleton();
services.TryAddSingleton();
+
+ services.TryAddSingleton(ArrayPool.Shared);
+ services.TryAddScoped();
}
}
}
diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewComponents/DefaultViewComponentHelper.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewComponents/DefaultViewComponentHelper.cs
index 792429d7c9..4de8c683c1 100644
--- a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewComponents/DefaultViewComponentHelper.cs
+++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewComponents/DefaultViewComponentHelper.cs
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Html;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewFeatures;
+using Microsoft.AspNet.Mvc.ViewFeatures.Buffer;
using Microsoft.AspNet.Mvc.ViewFeatures.Internal;
namespace Microsoft.AspNet.Mvc.ViewComponents
@@ -18,13 +19,15 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
private readonly HtmlEncoder _htmlEncoder;
private readonly IViewComponentInvokerFactory _invokerFactory;
private readonly IViewComponentSelector _selector;
+ private readonly IViewBufferScope _viewBufferScope;
private ViewContext _viewContext;
public DefaultViewComponentHelper(
IViewComponentDescriptorCollectionProvider descriptorProvider,
HtmlEncoder htmlEncoder,
IViewComponentSelector selector,
- IViewComponentInvokerFactory invokerFactory)
+ IViewComponentInvokerFactory invokerFactory,
+ IViewBufferScope viewBufferScope)
{
if (descriptorProvider == null)
{
@@ -46,10 +49,16 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
throw new ArgumentNullException(nameof(invokerFactory));
}
+ if (viewBufferScope == null)
+ {
+ throw new ArgumentNullException(nameof(viewBufferScope));
+ }
+
_descriptorProvider = descriptorProvider;
_htmlEncoder = htmlEncoder;
_selector = selector;
_invokerFactory = invokerFactory;
+ _viewBufferScope = viewBufferScope;
}
public void Contextualize(ViewContext viewContext)
@@ -71,10 +80,11 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
var descriptor = SelectComponent(name);
- using (var writer = new StringCollectionTextWriter(_viewContext.Writer.Encoding))
+ var viewBuffer = new ViewBuffer(_viewBufferScope, name);
+ using (var writer = new HtmlContentWrapperTextWriter(viewBuffer, _viewContext.Writer.Encoding))
{
InvokeCore(writer, descriptor, arguments);
- return writer.Content;
+ return writer.ContentBuilder;
}
}
@@ -86,11 +96,11 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
}
var descriptor = SelectComponent(componentType);
-
- using (var writer = new StringCollectionTextWriter(_viewContext.Writer.Encoding))
+ var viewBuffer = new ViewBuffer(_viewBufferScope, componentType.Name);
+ using (var writer = new HtmlContentWrapperTextWriter(viewBuffer, _viewContext.Writer.Encoding))
{
InvokeCore(writer, descriptor, arguments);
- return writer.Content;
+ return writer.ContentBuilder;
}
}
@@ -125,10 +135,11 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
var descriptor = SelectComponent(name);
- using (var writer = new StringCollectionTextWriter(_viewContext.Writer.Encoding))
+ var viewBuffer = new ViewBuffer(_viewBufferScope, name);
+ using (var writer = new HtmlContentWrapperTextWriter(viewBuffer, _viewContext.Writer.Encoding))
{
await InvokeCoreAsync(writer, descriptor, arguments);
- return writer.Content;
+ return writer.ContentBuilder;
}
}
@@ -141,10 +152,11 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
var descriptor = SelectComponent(componentType);
- using (var writer = new StringCollectionTextWriter(_viewContext.Writer.Encoding))
+ var viewBuffer = new ViewBuffer(_viewBufferScope, componentType.Name);
+ using (var writer = new HtmlContentWrapperTextWriter(viewBuffer, _viewContext.Writer.Encoding))
{
await InvokeCoreAsync(writer, descriptor, arguments);
- return writer.Content;
+ return writer.ContentBuilder;
}
}
diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/DefaultDisplayTemplates.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/DefaultDisplayTemplates.cs
index 049e132367..5081b41c07 100644
--- a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/DefaultDisplayTemplates.cs
+++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/DefaultDisplayTemplates.cs
@@ -10,9 +10,9 @@ using Microsoft.AspNet.Html;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewEngines;
+using Microsoft.AspNet.Mvc.ViewFeatures.Buffer;
using Microsoft.AspNet.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Internal;
namespace Microsoft.AspNet.Mvc.ViewFeatures
{
@@ -124,6 +124,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
var fieldNameBase = oldPrefix;
var result = new HtmlContentBuilder();
var viewEngine = serviceProvider.GetRequiredService();
+ var viewBufferScope = serviceProvider.GetRequiredService();
var index = 0;
foreach (var item in collection)
@@ -143,6 +144,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
var templateBuilder = new TemplateBuilder(
viewEngine,
+ viewBufferScope,
htmlHelper.ViewContext,
htmlHelper.ViewData,
modelExplorer,
@@ -223,6 +225,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
var serviceProvider = htmlHelper.ViewContext.HttpContext.RequestServices;
var viewEngine = serviceProvider.GetRequiredService();
+ var viewBufferScope = serviceProvider.GetRequiredService();
var content = new HtmlContentBuilder();
foreach (var propertyExplorer in modelExplorer.Properties)
@@ -235,6 +238,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
var templateBuilder = new TemplateBuilder(
viewEngine,
+ viewBufferScope,
htmlHelper.ViewContext,
htmlHelper.ViewData,
propertyExplorer,
diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/DefaultEditorTemplates.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/DefaultEditorTemplates.cs
index 87bf3bd671..c7ef0a4378 100644
--- a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/DefaultEditorTemplates.cs
+++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/DefaultEditorTemplates.cs
@@ -10,6 +10,7 @@ using Microsoft.AspNet.Html;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewEngines;
+using Microsoft.AspNet.Mvc.ViewFeatures.Buffer;
using Microsoft.AspNet.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.DependencyInjection;
@@ -87,6 +88,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
var fieldNameBase = oldPrefix;
var result = new HtmlContentBuilder();
var viewEngine = serviceProvider.GetRequiredService();
+ var viewBufferScope = serviceProvider.GetRequiredService();
var index = 0;
foreach (var item in collection)
@@ -106,6 +108,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
var templateBuilder = new TemplateBuilder(
viewEngine,
+ viewBufferScope,
htmlHelper.ViewContext,
htmlHelper.ViewData,
modelExplorer,
@@ -245,6 +248,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
var serviceProvider = htmlHelper.ViewContext.HttpContext.RequestServices;
var viewEngine = serviceProvider.GetRequiredService();
+ var viewBufferScope = serviceProvider.GetRequiredService();
var content = new HtmlContentBuilder();
foreach (var propertyExplorer in modelExplorer.Properties)
@@ -257,6 +261,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
var templateBuilder = new TemplateBuilder(
viewEngine,
+ viewBufferScope,
htmlHelper.ViewContext,
htmlHelper.ViewData,
propertyExplorer,
diff --git a/src/Microsoft.AspNet.Mvc.Razor/HtmlContentWrapperTextWriter.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/HtmlContentWrapperTextWriter.cs
similarity index 96%
rename from src/Microsoft.AspNet.Mvc.Razor/HtmlContentWrapperTextWriter.cs
rename to src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/HtmlContentWrapperTextWriter.cs
index 6a53c013a1..ab1610ab5e 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/HtmlContentWrapperTextWriter.cs
+++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/HtmlContentWrapperTextWriter.cs
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Html;
using Microsoft.AspNet.Mvc.Internal;
-namespace Microsoft.AspNet.Mvc.Razor
+namespace Microsoft.AspNet.Mvc.ViewFeatures
{
///
/// implementation which writes to an instance.
@@ -20,7 +20,7 @@ namespace Microsoft.AspNet.Mvc.Razor
/// Initializes a new instance of the class.
///
/// The to write to.
- /// The in which output is written.
+ /// The in which output is written.
public HtmlContentWrapperTextWriter(IHtmlContentBuilder contentBuilder, Encoding encoding)
{
if (contentBuilder == null)
diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/HtmlHelper.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/HtmlHelper.cs
index b0caa20804..6810a4f476 100644
--- a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/HtmlHelper.cs
+++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/HtmlHelper.cs
@@ -13,6 +13,7 @@ using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.ModelBinding.Validation;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewEngines;
+using Microsoft.AspNet.Mvc.ViewFeatures.Buffer;
using Microsoft.AspNet.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.Internal;
@@ -33,6 +34,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
private readonly IHtmlGenerator _htmlGenerator;
private readonly ICompositeViewEngine _viewEngine;
private readonly HtmlEncoder _htmlEncoder;
+ private readonly IViewBufferScope _bufferScope;
private ViewContext _viewContext;
@@ -43,6 +45,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
IHtmlGenerator htmlGenerator,
ICompositeViewEngine viewEngine,
IModelMetadataProvider metadataProvider,
+ IViewBufferScope bufferScope,
HtmlEncoder htmlEncoder,
UrlEncoder urlEncoder,
JavaScriptEncoder javaScriptEncoder)
@@ -62,6 +65,11 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
throw new ArgumentNullException(nameof(metadataProvider));
}
+ if (bufferScope == null)
+ {
+ throw new ArgumentNullException(nameof(bufferScope));
+ }
+
if (htmlEncoder == null)
{
throw new ArgumentNullException(nameof(htmlEncoder));
@@ -80,6 +88,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
_viewEngine = viewEngine;
_htmlGenerator = htmlGenerator;
_htmlEncoder = htmlEncoder;
+ _bufferScope = bufferScope;
MetadataProvider = metadataProvider;
UrlEncoder = urlEncoder;
JavaScriptEncoder = javaScriptEncoder;
@@ -349,10 +358,11 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
{
var metadata = ExpressionMetadataProvider.FromStringExpression(expression, ViewData, MetadataProvider);
- return GenerateDisplay(metadata,
- htmlFieldName ?? ExpressionHelper.GetExpressionText(expression),
- templateName,
- additionalViewData);
+ return GenerateDisplay(
+ metadata,
+ htmlFieldName ?? ExpressionHelper.GetExpressionText(expression),
+ templateName,
+ additionalViewData);
}
///
@@ -493,10 +503,11 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
throw new ArgumentNullException(nameof(partialViewName));
}
- using (var writer = new StringCollectionTextWriter(Encoding.UTF8))
+ var viewBuffer = new ViewBuffer(_bufferScope, partialViewName);
+ using (var writer = new HtmlContentWrapperTextWriter(viewBuffer, Encoding.UTF8))
{
await RenderPartialCoreAsync(partialViewName, model, viewData, writer);
- return writer.Content;
+ return writer.ContentBuilder;
}
}
@@ -519,6 +530,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
{
var templateBuilder = new TemplateBuilder(
_viewEngine,
+ _bufferScope,
ViewContext,
ViewData,
modelExplorer,
@@ -815,6 +827,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
{
var templateBuilder = new TemplateBuilder(
_viewEngine,
+ _bufferScope,
ViewContext,
ViewData,
modelExplorer,
diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/HtmlHelperOfT.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/HtmlHelperOfT.cs
index 1443767a2f..35745e27e2 100644
--- a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/HtmlHelperOfT.cs
+++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/HtmlHelperOfT.cs
@@ -9,6 +9,7 @@ using Microsoft.AspNet.Html;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewEngines;
+using Microsoft.AspNet.Mvc.ViewFeatures.Buffer;
namespace Microsoft.AspNet.Mvc.ViewFeatures
{
@@ -21,35 +22,19 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
IHtmlGenerator htmlGenerator,
ICompositeViewEngine viewEngine,
IModelMetadataProvider metadataProvider,
+ IViewBufferScope bufferScope,
HtmlEncoder htmlEncoder,
UrlEncoder urlEncoder,
JavaScriptEncoder javaScriptEncoder)
- : base(htmlGenerator, viewEngine, metadataProvider, htmlEncoder, urlEncoder, javaScriptEncoder)
+ : base(
+ htmlGenerator,
+ viewEngine,
+ metadataProvider,
+ bufferScope,
+ htmlEncoder,
+ urlEncoder,
+ javaScriptEncoder)
{
- if (htmlGenerator == null)
- {
- throw new ArgumentNullException(nameof(htmlGenerator));
- }
- if (viewEngine == null)
- {
- throw new ArgumentNullException(nameof(viewEngine));
- }
- if (metadataProvider == null)
- {
- throw new ArgumentNullException(nameof(metadataProvider));
- }
- if (htmlEncoder == null)
- {
- throw new ArgumentNullException(nameof(htmlEncoder));
- }
- if (urlEncoder == null)
- {
- throw new ArgumentNullException(nameof(urlEncoder));
- }
- if (javaScriptEncoder == null)
- {
- throw new ArgumentNullException(nameof(javaScriptEncoder));
- }
}
///
diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/StringCollectionTextWriter.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/StringCollectionTextWriter.cs
deleted file mode 100644
index bdac0103b7..0000000000
--- a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/StringCollectionTextWriter.cs
+++ /dev/null
@@ -1,260 +0,0 @@
-// 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 System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Text;
-using System.Text.Encodings.Web;
-using System.Threading.Tasks;
-using Microsoft.AspNet.Html;
-
-namespace Microsoft.AspNet.Mvc.ViewFeatures
-{
- ///
- /// A that stores individual write operations as a sequence of
- /// and instances.
- ///
- ///
- /// This is primarily designed to avoid creating large in-memory strings.
- /// Refer to https://aspnetwebstack.codeplex.com/workitem/585 for more details.
- ///
- public class StringCollectionTextWriter : HtmlTextWriter
- {
- private const int MaxCharToStringLength = 1024;
- private static readonly Task _completedTask = Task.FromResult(0);
-
- private readonly Encoding _encoding;
- private readonly StringCollectionTextWriterContent _content;
-
- ///
- /// Creates a new instance of .
- ///
- /// The character in which the output is written.
- public StringCollectionTextWriter(Encoding encoding)
- {
- _encoding = encoding;
- Entries = new List