Remove IHttpContextAccessor from TempData
This change removes the dependency of TempData on the IHttpContextAccessor by creating an ITempDataDictionaryFactory abstraction. In general, no one will replace the factory, it's just indirection. This allows us to drop our dependency on IHttpContextAccessor, and move it to the functional tests where we specifically depend on it. The bulk of code churn here is to update tests that use TempData.
This commit is contained in:
parent
70bdb6eb3e
commit
07085ca69b
|
|
@ -138,7 +138,6 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
services.TryAddSingleton<MvcMarkerService, MvcMarkerService>();
|
||||
services.TryAddSingleton<ITypeActivatorCache, DefaultTypeActivatorCache>();
|
||||
services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();
|
||||
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
services.TryAddSingleton<IUrlHelper, UrlHelper>();
|
||||
services.TryAddSingleton<IHttpRequestStreamReaderFactory, MemoryPoolHttpRequestStreamReaderFactory>();
|
||||
services.TryAddSingleton<IHttpResponseStreamWriterFactory, MemoryPoolHttpResponseStreamWriterFactory>();
|
||||
|
|
|
|||
|
|
@ -260,7 +260,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
if (_tempData == null)
|
||||
{
|
||||
_tempData = Resolver?.GetRequiredService<ITempDataDictionary>();
|
||||
var factory = Resolver?.GetRequiredService<ITempDataDictionaryFactory>();
|
||||
_tempData = factory?.GetTempData(HttpContext);
|
||||
}
|
||||
|
||||
return _tempData;
|
||||
|
|
|
|||
|
|
@ -101,10 +101,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
//
|
||||
services.TryAddTransient<IHtmlHelper, HtmlHelper>();
|
||||
services.TryAddTransient(typeof(IHtmlHelper<>), typeof(HtmlHelper<>));
|
||||
|
||||
// DefaultHtmlGenerator is pretty much stateless but depends on IUrlHelper, which is scoped.
|
||||
// Therefore it too is scoped.
|
||||
services.TryAddScoped<IHtmlGenerator, DefaultHtmlGenerator>();
|
||||
services.TryAddSingleton<IHtmlGenerator, DefaultHtmlGenerator>();
|
||||
|
||||
//
|
||||
// JSON Helper
|
||||
|
|
@ -133,12 +130,12 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
//
|
||||
// Temp Data
|
||||
//
|
||||
// Holds per-request data so it should be scoped
|
||||
services.TryAddScoped<ITempDataDictionary, TempDataDictionary>();
|
||||
services.TryAddScoped<SaveTempDataFilter>();
|
||||
|
||||
// This does caching so it should stay singleton
|
||||
services.TryAddSingleton<ITempDataProvider, SessionStateTempDataProvider>();
|
||||
|
||||
// These are stateless so their lifetime isn't really important.
|
||||
services.TryAddSingleton<ITempDataDictionaryFactory, TempDataDictionaryFactory>();
|
||||
services.TryAddSingleton<SaveTempDataFilter>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
var tempData = TempData;
|
||||
if (tempData == null)
|
||||
{
|
||||
tempData = services.GetRequiredService<ITempDataDictionary>();
|
||||
var factory = services.GetRequiredService<ITempDataDictionaryFactory>();
|
||||
tempData = factory.GetTempData(context.HttpContext);
|
||||
}
|
||||
|
||||
string resolvedContentType = null;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
// 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.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ViewFeatures
|
||||
{
|
||||
/// <summary>
|
||||
/// A factory which provides access to an <see cref="ITempDataDictionary"/> instance
|
||||
/// for a request.
|
||||
/// </summary>
|
||||
public interface ITempDataDictionaryFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or creates an <see cref="ITempDataDictionary"/> instance for the request associated with the
|
||||
/// given <paramref name="context"/>.
|
||||
/// </summary>
|
||||
/// <param name="context">The <see cref="HttpContext"/>.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="ITempDataDictionary"/> instance for the request associated with the given
|
||||
/// <paramref name="context"/>.
|
||||
/// </returns>
|
||||
ITempDataDictionary GetTempData(HttpContext context);
|
||||
}
|
||||
}
|
||||
|
|
@ -27,15 +27,17 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
/// <param name="viewOptions">The <see cref="IOptions{MvcViewOptions}"/>.</param>
|
||||
/// <param name="writerFactory">The <see cref="IHttpResponseStreamWriterFactory"/>.</param>
|
||||
/// <param name="viewEngine">The <see cref="ICompositeViewEngine"/>.</param>
|
||||
/// <param name="tempDataFactory">The <see cref="ITempDataDictionaryFactory"/>.</param>
|
||||
/// <param name="diagnosticSource">The <see cref="DiagnosticSource"/>.</param>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public PartialViewResultExecutor(
|
||||
IOptions<MvcViewOptions> viewOptions,
|
||||
IHttpResponseStreamWriterFactory writerFactory,
|
||||
ICompositeViewEngine viewEngine,
|
||||
ITempDataDictionaryFactory tempDataFactory,
|
||||
DiagnosticSource diagnosticSource,
|
||||
ILoggerFactory loggerFactory)
|
||||
: base(viewOptions, writerFactory, viewEngine, diagnosticSource)
|
||||
: base(viewOptions, writerFactory, viewEngine, tempDataFactory, diagnosticSource)
|
||||
{
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,15 +10,15 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
/// </summary>
|
||||
public class SaveTempDataFilter : IResourceFilter, IResultFilter
|
||||
{
|
||||
private readonly ITempDataDictionary _tempData;
|
||||
private readonly ITempDataDictionaryFactory _factory;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="SaveTempDataFilter"/>.
|
||||
/// </summary>
|
||||
/// <param name="tempData">The <see cref="ITempDataDictionary"/> for the current request.</param>
|
||||
public SaveTempDataFilter(ITempDataDictionary tempData)
|
||||
/// <param name="factory">The <see cref="ITempDataDictionaryFactory"/>.</param>
|
||||
public SaveTempDataFilter(ITempDataDictionaryFactory factory)
|
||||
{
|
||||
_tempData = tempData;
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
/// <inheritdoc />
|
||||
public void OnResourceExecuted(ResourceExecutedContext context)
|
||||
{
|
||||
_tempData.Save();
|
||||
_factory.GetTempData(context.HttpContext).Save();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
{
|
||||
if (context.Result is IKeepTempDataResult)
|
||||
{
|
||||
_tempData.Keep();
|
||||
_factory.GetTempData(context.HttpContext).Keep();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,16 +14,16 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
private Dictionary<string, object> _data;
|
||||
private bool _loaded;
|
||||
private readonly ITempDataProvider _provider;
|
||||
private readonly IHttpContextAccessor _contextAccessor;
|
||||
private readonly HttpContext _context;
|
||||
private HashSet<string> _initialKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
private HashSet<string> _retainedKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TempDataDictionary"/> class.
|
||||
/// </summary>
|
||||
/// <param name="context">The <see cref="IHttpContextAccessor"/> that provides the HttpContext.</param>
|
||||
/// <param name="context">The <see cref="HttpContext"/>.</param>
|
||||
/// <param name="provider">The <see cref="ITempDataProvider"/> used to Load and Save data.</param>
|
||||
public TempDataDictionary(IHttpContextAccessor context, ITempDataProvider provider)
|
||||
public TempDataDictionary(HttpContext context, ITempDataProvider provider)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
|
|
@ -37,7 +37,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
|
||||
_provider = provider;
|
||||
_loaded = false;
|
||||
_contextAccessor = context;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public int Count
|
||||
|
|
@ -127,7 +127,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
return;
|
||||
}
|
||||
|
||||
var providerDictionary = _provider.LoadTempData(_contextAccessor.HttpContext);
|
||||
var providerDictionary = _provider.LoadTempData(_context);
|
||||
_data = (providerDictionary != null)
|
||||
? new Dictionary<string, object>(providerDictionary, StringComparer.OrdinalIgnoreCase)
|
||||
: new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
|
|
@ -161,7 +161,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
_data.Remove(keys[i]);
|
||||
}
|
||||
|
||||
_provider.SaveTempData(_contextAccessor.HttpContext, _data);
|
||||
_provider.SaveTempData(_context, _data);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
// 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 Microsoft.AspNet.Http;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ViewFeatures
|
||||
{
|
||||
/// <summary>
|
||||
/// A default implementation of <see cref="ITempDataDictionaryFactory"/>.
|
||||
/// </summary>
|
||||
public class TempDataDictionaryFactory : ITempDataDictionaryFactory
|
||||
{
|
||||
private static readonly object Key = typeof(ITempDataDictionary);
|
||||
|
||||
private readonly ITempDataProvider _provider;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="TempDataDictionaryFactory"/>.
|
||||
/// </summary>
|
||||
/// <param name="provider">The <see cref="ITempDataProvider"/>.</param>
|
||||
public TempDataDictionaryFactory(ITempDataProvider provider)
|
||||
{
|
||||
if (provider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(provider));
|
||||
}
|
||||
|
||||
_provider = provider;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITempDataDictionary GetTempData(HttpContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
object obj;
|
||||
ITempDataDictionary result;
|
||||
if (context.Items.TryGetValue(Key, out obj))
|
||||
{
|
||||
result = (ITempDataDictionary)obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new TempDataDictionary(context, _provider);
|
||||
context.Items.Add(Key, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -36,11 +36,13 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
/// <param name="viewOptions">The <see cref="IOptions{MvcViewOptions}"/>.</param>
|
||||
/// <param name="writerFactory">The <see cref="IHttpResponseStreamWriterFactory"/>.</param>
|
||||
/// <param name="viewEngine">The <see cref="ICompositeViewEngine"/>.</param>
|
||||
/// <param name="tempDataFactory">The <see cref="ITempDataDictionaryFactory"/>.</param>
|
||||
/// <param name="diagnosticSource">The <see cref="DiagnosticSource"/>.</param>
|
||||
public ViewExecutor(
|
||||
IOptions<MvcViewOptions> viewOptions,
|
||||
IHttpResponseStreamWriterFactory writerFactory,
|
||||
ICompositeViewEngine viewEngine,
|
||||
ITempDataDictionaryFactory tempDataFactory,
|
||||
DiagnosticSource diagnosticSource)
|
||||
{
|
||||
if (viewOptions == null)
|
||||
|
|
@ -58,6 +60,11 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
throw new ArgumentNullException(nameof(viewEngine));
|
||||
}
|
||||
|
||||
if (tempDataFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(tempDataFactory));
|
||||
}
|
||||
|
||||
if (diagnosticSource == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(diagnosticSource));
|
||||
|
|
@ -66,6 +73,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
ViewOptions = viewOptions.Value;
|
||||
WriterFactory = writerFactory;
|
||||
ViewEngine = viewEngine;
|
||||
TempDataFactory = tempDataFactory;
|
||||
DiagnosticSource = diagnosticSource;
|
||||
}
|
||||
|
||||
|
|
@ -74,6 +82,11 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
/// </summary>
|
||||
protected DiagnosticSource DiagnosticSource { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ITempDataDictionaryFactory"/>.
|
||||
/// </summary>
|
||||
protected ITempDataDictionaryFactory TempDataFactory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default <see cref="IViewEngine"/>.
|
||||
/// </summary>
|
||||
|
|
@ -131,7 +144,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
|
||||
if (tempData == null)
|
||||
{
|
||||
tempData = services.GetRequiredService<ITempDataDictionary>();
|
||||
tempData = TempDataFactory.GetTempData(actionContext.HttpContext);
|
||||
}
|
||||
|
||||
var response = actionContext.HttpContext.Response;
|
||||
|
|
|
|||
|
|
@ -25,15 +25,17 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
/// <param name="viewOptions">The <see cref="IOptions{MvcViewOptions}"/>.</param>
|
||||
/// <param name="writerFactory">The <see cref="IHttpResponseStreamWriterFactory"/>.</param>
|
||||
/// <param name="viewEngine">The <see cref="ICompositeViewEngine"/>.</param>
|
||||
/// <param name="tempDataFactory">The <see cref="ITempDataDictionaryFactory"/>.</param>
|
||||
/// <param name="diagnosticSource">The <see cref="DiagnosticSource"/>.</param>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
|
||||
public ViewResultExecutor(
|
||||
IOptions<MvcViewOptions> viewOptions,
|
||||
IHttpResponseStreamWriterFactory writerFactory,
|
||||
ICompositeViewEngine viewEngine,
|
||||
ITempDataDictionaryFactory tempDataFactory,
|
||||
DiagnosticSource diagnosticSource,
|
||||
ILoggerFactory loggerFactory)
|
||||
: base(viewOptions, writerFactory, viewEngine, diagnosticSource)
|
||||
: base(viewOptions, writerFactory, viewEngine, tempDataFactory, diagnosticSource)
|
||||
{
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -968,7 +968,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
var controller = new TestableController()
|
||||
{
|
||||
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
|
||||
TempData = new TempDataDictionary(Mock.Of<IHttpContextAccessor>(), Mock.Of<ITempDataProvider>()),
|
||||
TempData = new TempDataDictionary(new DefaultHttpContext(), Mock.Of<ITempDataProvider>()),
|
||||
};
|
||||
|
||||
// Act
|
||||
|
|
@ -989,7 +989,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
var controller = new TestableController()
|
||||
{
|
||||
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
|
||||
TempData = new TempDataDictionary(Mock.Of<IHttpContextAccessor>(), Mock.Of<ITempDataProvider>()),
|
||||
TempData = new TempDataDictionary(new DefaultHttpContext(), Mock.Of<ITempDataProvider>()),
|
||||
};
|
||||
|
||||
// Act
|
||||
|
|
@ -1010,7 +1010,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
var controller = new TestableController()
|
||||
{
|
||||
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
|
||||
TempData = new TempDataDictionary(Mock.Of<IHttpContextAccessor>(), Mock.Of<ITempDataProvider>()),
|
||||
TempData = new TempDataDictionary(new DefaultHttpContext(), Mock.Of<ITempDataProvider>()),
|
||||
};
|
||||
var model = new object();
|
||||
|
||||
|
|
@ -1032,7 +1032,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
var controller = new TestableController()
|
||||
{
|
||||
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
|
||||
TempData = new TempDataDictionary(Mock.Of<IHttpContextAccessor>(), Mock.Of<ITempDataProvider>()),
|
||||
TempData = new TempDataDictionary(new DefaultHttpContext(), Mock.Of<ITempDataProvider>()),
|
||||
};
|
||||
var model = new object();
|
||||
|
||||
|
|
@ -1856,7 +1856,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
var httpContext = new DefaultHttpContext();
|
||||
|
||||
var viewData = new ViewDataDictionary(metadataProvider, new ModelStateDictionary());
|
||||
var tempData = new TempDataDictionary(Mock.Of<IHttpContextAccessor>(), Mock.Of<ITempDataProvider>());
|
||||
var tempData = new TempDataDictionary(httpContext, Mock.Of<ITempDataProvider>());
|
||||
|
||||
var controllerContext = new ControllerContext()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
options,
|
||||
new TestHttpResponseStreamWriterFactory(),
|
||||
new CompositeViewEngine(options),
|
||||
new TempDataDictionaryFactory(new SessionStateTempDataProvider()),
|
||||
new DiagnosticListener("Microsoft.AspNet"),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
Mock.Of<IView>(),
|
||||
viewData,
|
||||
new TempDataDictionary(
|
||||
new HttpContextAccessor(),
|
||||
httpContext,
|
||||
Mock.Of<ITempDataProvider>()),
|
||||
new StringWriter(),
|
||||
options.HtmlHelperOptions);
|
||||
|
|
|
|||
|
|
@ -20,12 +20,13 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
public void SettingViewData_AlsoUpdatesViewBag()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
var originalViewData = new ViewDataDictionary(metadataProvider: new EmptyModelMetadataProvider());
|
||||
var context = new ViewContext(
|
||||
new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()),
|
||||
view: Mock.Of<IView>(),
|
||||
viewData: originalViewData,
|
||||
tempData: new TempDataDictionary(new HttpContextAccessor(), Mock.Of<ITempDataProvider>()),
|
||||
tempData: new TempDataDictionary(httpContext, Mock.Of<ITempDataProvider>()),
|
||||
writer: TextWriter.Null,
|
||||
htmlHelperOptions: new HtmlHelperOptions());
|
||||
var replacementViewData = new ViewDataDictionary(metadataProvider: new EmptyModelMetadataProvider());
|
||||
|
|
@ -47,11 +48,12 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
public void CopyConstructor_CopiesExpectedProperties()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new DefaultHttpContext();
|
||||
var originalContext = new ViewContext(
|
||||
new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()),
|
||||
new ActionContext(httpContext, new RouteData(), new ActionDescriptor()),
|
||||
view: Mock.Of<IView>(),
|
||||
viewData: new ViewDataDictionary(metadataProvider: new EmptyModelMetadataProvider()),
|
||||
tempData: new TempDataDictionary(new HttpContextAccessor(), Mock.Of<ITempDataProvider>()),
|
||||
tempData: new TempDataDictionary(httpContext, Mock.Of<ITempDataProvider>()),
|
||||
writer: TextWriter.Null,
|
||||
htmlHelperOptions: new HtmlHelperOptions());
|
||||
var view = Mock.Of<IView>();
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
public class ViewComponentResultTest
|
||||
{
|
||||
private readonly ITempDataDictionary _tempDataDictionary =
|
||||
new TempDataDictionary(new HttpContextAccessor(), new SessionStateTempDataProvider());
|
||||
new TempDataDictionary(new DefaultHttpContext(), new SessionStateTempDataProvider());
|
||||
|
||||
[Fact]
|
||||
public async Task ExecuteAsync_ViewComponentResult_AllowsNullViewDataAndTempData()
|
||||
|
|
@ -460,8 +460,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
private IServiceCollection CreateServices(object diagnosticListener, HttpContext context, params ViewComponentDescriptor[] descriptors)
|
||||
{
|
||||
var httpContext = new HttpContextAccessor() { HttpContext = context };
|
||||
var tempDataProvider = new SessionStateTempDataProvider();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
var diagnosticSource = new DiagnosticListener("Microsoft.AspNet");
|
||||
if (diagnosticListener != null)
|
||||
{
|
||||
|
|
@ -480,8 +479,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
services.AddSingleton<IViewComponentDescriptorProvider>(new FixedSetViewComponentDescriptorProvider(descriptors));
|
||||
services.AddSingleton<IModelMetadataProvider, EmptyModelMetadataProvider>();
|
||||
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
|
||||
services.AddSingleton<ITempDataDictionary>(new TempDataDictionary(httpContext, tempDataProvider));
|
||||
services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();
|
||||
services.AddSingleton<ITempDataDictionaryFactory, TempDataDictionaryFactory>();
|
||||
services.AddSingleton<ITempDataProvider, SessionStateTempDataProvider>();
|
||||
services.AddSingleton<HtmlEncoder, HtmlTestEncoder>();
|
||||
|
||||
return services;
|
||||
|
|
|
|||
|
|
@ -37,13 +37,14 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
private static ViewComponentContext GetViewComponentContext(IView view, Stream stream)
|
||||
{
|
||||
var actionContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
|
||||
var httpContext = new DefaultHttpContext();
|
||||
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
|
||||
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
|
||||
var viewContext = new ViewContext(
|
||||
actionContext,
|
||||
view,
|
||||
viewData,
|
||||
new TempDataDictionary(new HttpContextAccessor(), new SessionStateTempDataProvider()),
|
||||
viewData,
|
||||
new TempDataDictionary(httpContext, new SessionStateTempDataProvider()),
|
||||
TextWriter.Null,
|
||||
new HtmlHelperOptions());
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
actionContext,
|
||||
view,
|
||||
viewData,
|
||||
new TempDataDictionary(new HttpContextAccessor(), new SessionStateTempDataProvider()),
|
||||
new TempDataDictionary(actionContext.HttpContext, new SessionStateTempDataProvider()),
|
||||
TextWriter.Null,
|
||||
new HtmlHelperOptions());
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
public class ViewViewComponentResultTest
|
||||
{
|
||||
private readonly ITempDataDictionary _tempDataDictionary =
|
||||
new TempDataDictionary(new HttpContextAccessor(), new SessionStateTempDataProvider());
|
||||
new TempDataDictionary(new DefaultHttpContext(), new SessionStateTempDataProvider());
|
||||
|
||||
[Fact]
|
||||
public void Execute_RendersPartialViews()
|
||||
|
|
@ -527,7 +527,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
actionContext,
|
||||
view,
|
||||
viewData,
|
||||
new TempDataDictionary(new HttpContextAccessor(), new SessionStateTempDataProvider()),
|
||||
new TempDataDictionary(httpContext, new SessionStateTempDataProvider()),
|
||||
TextWriter.Null,
|
||||
new HtmlHelperOptions());
|
||||
|
||||
|
|
|
|||
|
|
@ -337,6 +337,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
options,
|
||||
new TestHttpResponseStreamWriterFactory(),
|
||||
new CompositeViewEngine(options),
|
||||
new TempDataDictionaryFactory(new SessionStateTempDataProvider()),
|
||||
diagnosticSource,
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Internal;
|
||||
using Microsoft.AspNet.Mvc.Abstractions;
|
||||
using Microsoft.AspNet.Mvc.Filters;
|
||||
|
|
@ -21,7 +22,12 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
.Setup(m => m.Save())
|
||||
.Verifiable();
|
||||
|
||||
var filter = new SaveTempDataFilter(tempData.Object);
|
||||
var tempDataFactory = new Mock<ITempDataDictionaryFactory>(MockBehavior.Strict);
|
||||
tempDataFactory
|
||||
.Setup(f => f.GetTempData(It.IsAny<HttpContext>()))
|
||||
.Returns(tempData.Object);
|
||||
|
||||
var filter = new SaveTempDataFilter(tempDataFactory.Object);
|
||||
|
||||
var context = new ResourceExecutedContext(
|
||||
new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()),
|
||||
|
|
@ -43,7 +49,12 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
.Setup(m => m.Keep())
|
||||
.Verifiable();
|
||||
|
||||
var filter = new SaveTempDataFilter(tempData.Object);
|
||||
var tempDataFactory = new Mock<ITempDataDictionaryFactory>(MockBehavior.Strict);
|
||||
tempDataFactory
|
||||
.Setup(f => f.GetTempData(It.IsAny<HttpContext>()))
|
||||
.Returns(tempData.Object);
|
||||
|
||||
var filter = new SaveTempDataFilter(tempDataFactory.Object);
|
||||
|
||||
var context = new ResultExecutedContext(
|
||||
new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()),
|
||||
|
|
@ -63,7 +74,13 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
{
|
||||
// Arrange
|
||||
var tempData = new Mock<ITempDataDictionary>(MockBehavior.Strict);
|
||||
var filter = new SaveTempDataFilter(tempData.Object);
|
||||
|
||||
var tempDataFactory = new Mock<ITempDataDictionaryFactory>(MockBehavior.Strict);
|
||||
tempDataFactory
|
||||
.Setup(f => f.GetTempData(It.IsAny<HttpContext>()))
|
||||
.Returns(tempData.Object);
|
||||
|
||||
var filter = new SaveTempDataFilter(tempDataFactory.Object);
|
||||
|
||||
var context = new ResultExecutedContext(
|
||||
new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()),
|
||||
|
|
@ -77,4 +94,4 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
// Assert - The mock will throw if we do the wrong thing.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
// 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.AspNet.Http.Internal;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ViewFeatures
|
||||
{
|
||||
public class TempDataDictionaryFactoryTest
|
||||
{
|
||||
[Fact]
|
||||
public void Factory_CreatesTempData_ForEachHttpContext()
|
||||
{
|
||||
// Arrange
|
||||
var factory = CreateFactory();
|
||||
|
||||
var context1 = new DefaultHttpContext();
|
||||
var context2 = new DefaultHttpContext();
|
||||
|
||||
var tempData1 = factory.GetTempData(context1);
|
||||
|
||||
// Act
|
||||
var tempData2 = factory.GetTempData(context2);
|
||||
|
||||
// Assert
|
||||
Assert.NotSame(tempData1, tempData2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Factory_StoresTempData_InHttpContext()
|
||||
{
|
||||
// Arrange
|
||||
var factory = CreateFactory();
|
||||
|
||||
var context = new DefaultHttpContext();
|
||||
|
||||
var tempData1 = factory.GetTempData(context);
|
||||
|
||||
// Act
|
||||
var tempData2 = factory.GetTempData(context);
|
||||
|
||||
// Assert
|
||||
Assert.Same(tempData1, tempData2);
|
||||
}
|
||||
|
||||
private TempDataDictionaryFactory CreateFactory()
|
||||
{
|
||||
var provider = new SessionStateTempDataProvider();
|
||||
return new TempDataDictionaryFactory(provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
public void ThrowscdException_OnSettingValue_AndWhenSessionIsNotEnabled()
|
||||
{
|
||||
// Arrange
|
||||
var tempData = new TempDataDictionary(GetHttpContextAccessor(), new SessionStateTempDataProvider());
|
||||
var tempData = new TempDataDictionary(new DefaultHttpContext(), new SessionStateTempDataProvider());
|
||||
|
||||
// Act & Assert
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
|
|
@ -28,7 +28,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
public void Keep_DoesNotThrowException_WhenDataIsNotLoaded()
|
||||
{
|
||||
// Arrange
|
||||
var tempData = new TempDataDictionary(GetHttpContextAccessor(), new SessionStateTempDataProvider());
|
||||
var tempData = new TempDataDictionary(new DefaultHttpContext(), new SessionStateTempDataProvider());
|
||||
|
||||
// Act & Assert
|
||||
tempData.Keep();
|
||||
|
|
@ -38,7 +38,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
public void TempData_Load_CreatesEmptyDictionaryIfProviderReturnsNull()
|
||||
{
|
||||
// Arrange
|
||||
var tempData = new TempDataDictionary(GetHttpContextAccessor(), new NullTempDataProvider());
|
||||
var tempData = new TempDataDictionary(new DefaultHttpContext(), new NullTempDataProvider());
|
||||
|
||||
// Act
|
||||
tempData.Load();
|
||||
|
|
@ -51,7 +51,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
public void TempData_Save_RemovesKeysThatWereRead()
|
||||
{
|
||||
// Arrange
|
||||
var tempData = new TempDataDictionary(GetHttpContextAccessor(), new NullTempDataProvider());
|
||||
var tempData = new TempDataDictionary(new DefaultHttpContext(), new NullTempDataProvider());
|
||||
tempData["Foo"] = "Foo";
|
||||
tempData["Bar"] = "Bar";
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
public void TempData_EnumeratingDictionary_MarksKeysForDeletion()
|
||||
{
|
||||
// Arrange
|
||||
var tempData = new TempDataDictionary(GetHttpContextAccessor(), new NullTempDataProvider());
|
||||
var tempData = new TempDataDictionary(new DefaultHttpContext(), new NullTempDataProvider());
|
||||
tempData["Foo"] = "Foo";
|
||||
tempData["Bar"] = "Bar";
|
||||
|
||||
|
|
@ -88,7 +88,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
[Fact]
|
||||
public void TempData_TryGetValue_MarksKeyForDeletion()
|
||||
{
|
||||
var tempData = new TempDataDictionary(GetHttpContextAccessor(), new NullTempDataProvider());
|
||||
var tempData = new TempDataDictionary(new DefaultHttpContext(), new NullTempDataProvider());
|
||||
object value;
|
||||
tempData["Foo"] = "Foo";
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
public void TempData_Keep_RetainsAllKeysWhenSavingDictionary()
|
||||
{
|
||||
// Arrange
|
||||
var tempData = new TempDataDictionary(GetHttpContextAccessor(), new NullTempDataProvider());
|
||||
var tempData = new TempDataDictionary(new DefaultHttpContext(), new NullTempDataProvider());
|
||||
tempData["Foo"] = "Foo";
|
||||
tempData["Bar"] = "Bar";
|
||||
|
||||
|
|
@ -121,7 +121,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
public void TempData_Keep_RetainsSpecificKeysWhenSavingDictionary()
|
||||
{
|
||||
// Arrange
|
||||
var tempData = new TempDataDictionary(GetHttpContextAccessor(), new NullTempDataProvider());
|
||||
var tempData = new TempDataDictionary(new DefaultHttpContext(), new NullTempDataProvider());
|
||||
tempData["Foo"] = "Foo";
|
||||
tempData["Bar"] = "Bar";
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
public void TempData_Peek_DoesNotMarkKeyForDeletion()
|
||||
{
|
||||
// Arrange
|
||||
var tempData = new TempDataDictionary(GetHttpContextAccessor(), new NullTempDataProvider());
|
||||
var tempData = new TempDataDictionary(new DefaultHttpContext(), new NullTempDataProvider());
|
||||
tempData["Bar"] = "barValue";
|
||||
|
||||
// Act
|
||||
|
|
@ -156,7 +156,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
public void TempData_CompareIsOrdinalIgnoreCase()
|
||||
{
|
||||
// Arrange
|
||||
var tempData = new TempDataDictionary(GetHttpContextAccessor(), new NullTempDataProvider());
|
||||
var tempData = new TempDataDictionary(new DefaultHttpContext(), new NullTempDataProvider());
|
||||
var item = new object();
|
||||
|
||||
// Act
|
||||
|
|
@ -175,7 +175,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
data["Foo"] = "Foo";
|
||||
data["Bar"] = "Bar";
|
||||
var provider = new TestTempDataProvider(data);
|
||||
var tempData = new TempDataDictionary(GetHttpContextAccessor(), provider);
|
||||
var tempData = new TempDataDictionary(new DefaultHttpContext(), provider);
|
||||
|
||||
// Act
|
||||
tempData.Load();
|
||||
|
|
@ -190,7 +190,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
[Fact]
|
||||
public void TempData_RemovalOfKeysAreCaseInsensitive()
|
||||
{
|
||||
var tempData = new TempDataDictionary(GetHttpContextAccessor(), new NullTempDataProvider());
|
||||
var tempData = new TempDataDictionary(new DefaultHttpContext(), new NullTempDataProvider());
|
||||
object fooValue;
|
||||
tempData["Foo"] = "Foo";
|
||||
tempData["Bar"] = "Bar";
|
||||
|
|
@ -235,10 +235,5 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static IHttpContextAccessor GetHttpContextAccessor()
|
||||
{
|
||||
return new HttpContextAccessor() { HttpContext = new DefaultHttpContext() };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -125,7 +125,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
|
||||
private static IServiceProvider GetServiceProvider()
|
||||
{
|
||||
var httpContext = new HttpContextAccessor() { HttpContext = new DefaultHttpContext() };
|
||||
var httpContext = new DefaultHttpContext();
|
||||
var serviceCollection = new ServiceCollection();
|
||||
serviceCollection.AddSingleton<IModelMetadataProvider>(new EmptyModelMetadataProvider());
|
||||
var tempDataProvider = new SessionStateTempDataProvider();
|
||||
|
|
@ -357,6 +357,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
new TestOptionsManager<MvcViewOptions>(),
|
||||
new TestHttpResponseStreamWriterFactory(),
|
||||
new Mock<ICompositeViewEngine>(MockBehavior.Strict).Object,
|
||||
new TempDataDictionaryFactory(new SessionStateTempDataProvider()),
|
||||
diagnosticSource);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -333,6 +333,7 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
|||
options,
|
||||
new TestHttpResponseStreamWriterFactory(),
|
||||
new CompositeViewEngine(options),
|
||||
new TempDataDictionaryFactory(new SessionStateTempDataProvider()),
|
||||
diagnosticSource,
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
options,
|
||||
new TestHttpResponseStreamWriterFactory(),
|
||||
new CompositeViewEngine(options),
|
||||
new TempDataDictionaryFactory(new SessionStateTempDataProvider()),
|
||||
new DiagnosticListener("Microsoft.AspNet"),
|
||||
NullLoggerFactory.Instance);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ using System;
|
|||
using System.Reflection;
|
||||
using ControllersFromServicesClassLibrary;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ControllersFromServicesWebSite
|
||||
|
|
@ -21,6 +23,7 @@ namespace ControllersFromServicesWebSite
|
|||
});
|
||||
|
||||
services.AddTransient<QueryValueService>();
|
||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace RequestServicesWebSite
|
||||
|
|
@ -14,6 +16,7 @@ namespace RequestServicesWebSite
|
|||
services.AddMvc();
|
||||
|
||||
services.AddScoped<RequestIdService>();
|
||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
|
|
|
|||
Loading…
Reference in New Issue