diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionBindingContextAccessor.cs b/src/Microsoft.AspNet.Mvc.Core/ActionBindingContextAccessor.cs new file mode 100644 index 0000000000..278ab08054 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/ActionBindingContextAccessor.cs @@ -0,0 +1,40 @@ +// 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. + +#if DNX451 +using System.Runtime.Remoting; +using System.Runtime.Remoting.Messaging; +#else +using System.Threading; +#endif + +namespace Microsoft.AspNet.Mvc +{ + public class ActionBindingContextAccessor : IActionBindingContextAccessor + { +#if DNX451 + private static string Key = typeof(ActionBindingContext).FullName; + + public ActionBindingContext ActionBindingContext + { + get + { + var handle = CallContext.LogicalGetData(Key) as ObjectHandle; + return handle != null ? (ActionBindingContext)handle.Unwrap() : null; + } + set + { + CallContext.LogicalSetData(Key, new ObjectHandle(value)); + } + } +#else + private readonly AsyncLocal _storage = new AsyncLocal(); + + public ActionBindingContext ActionBindingContext + { + get { return _storage.Value; } + set { _storage.Value = value; } + } +#endif + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionContextAccessor.cs b/src/Microsoft.AspNet.Mvc.Core/ActionContextAccessor.cs new file mode 100644 index 0000000000..4feeb26838 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/ActionContextAccessor.cs @@ -0,0 +1,40 @@ +// 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. + +#if DNX451 +using System.Runtime.Remoting; +using System.Runtime.Remoting.Messaging; +#else +using System.Threading; +#endif + +namespace Microsoft.AspNet.Mvc +{ + public class ActionContextAccessor : IActionContextAccessor + { +#if DNX451 + private static string Key = typeof(ActionContext).FullName; + + public ActionContext ActionContext + { + get + { + var handle = CallContext.LogicalGetData(Key) as ObjectHandle; + return handle != null ? (ActionContext)handle.Unwrap() : null; + } + set + { + CallContext.LogicalSetData(Key, new ObjectHandle(value)); + } + } +#else + private readonly AsyncLocal _storage = new AsyncLocal(); + + public ActionContext ActionContext + { + get { return _storage.Value; } + set { _storage.Value = value; } + } +#endif + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvoker.cs index 0a8504b522..2feb17ab07 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvoker.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvoker.cs @@ -30,8 +30,8 @@ namespace Microsoft.AspNet.Mvc.Core [NotNull] IReadOnlyList modelBinders, [NotNull] IReadOnlyList modelValidatorProviders, [NotNull] IReadOnlyList valueProviderFactories, - [NotNull] IScopedInstance actionBindingContextAccessor, - [NotNull] ILoggerFactory loggerFactory, + [NotNull] IActionBindingContextAccessor actionBindingContextAccessor, + [NotNull] ILogger logger, int maxModelValidationErrors) : base( actionContext, @@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Mvc.Core modelValidatorProviders, valueProviderFactories, actionBindingContextAccessor, - loggerFactory, + logger, maxModelValidationErrors) { _descriptor = descriptor; diff --git a/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvokerProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvokerProvider.cs index 4699b06a08..943e8acd26 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvokerProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvokerProvider.cs @@ -21,16 +21,16 @@ namespace Microsoft.AspNet.Mvc.Core private readonly IReadOnlyList _outputFormatters; private readonly IReadOnlyList _modelValidatorProviders; private readonly IReadOnlyList _valueProviderFactories; - private readonly IScopedInstance _actionBindingContextAccessor; + private readonly IActionBindingContextAccessor _actionBindingContextAccessor; private readonly int _maxModelValidationErrors; - private readonly ILoggerFactory _loggerFactory; + private readonly ILogger _logger; public ControllerActionInvokerProvider( IControllerFactory controllerFactory, IEnumerable filterProviders, IControllerActionArgumentBinder argumentBinder, IOptions optionsAccessor, - IScopedInstance actionBindingContextAccessor, + IActionBindingContextAccessor actionBindingContextAccessor, ILoggerFactory loggerFactory) { _controllerFactory = controllerFactory; @@ -43,7 +43,8 @@ namespace Microsoft.AspNet.Mvc.Core _valueProviderFactories = optionsAccessor.Options.ValueProviderFactories.ToArray(); _actionBindingContextAccessor = actionBindingContextAccessor; _maxModelValidationErrors = optionsAccessor.Options.MaxModelValidationErrors; - _loggerFactory = loggerFactory; + + _logger = loggerFactory.CreateLogger(); } public int Order @@ -70,7 +71,7 @@ namespace Microsoft.AspNet.Mvc.Core _modelValidatorProviders, _valueProviderFactories, _actionBindingContextAccessor, - _loggerFactory, + _logger, _maxModelValidationErrors); } } diff --git a/src/Microsoft.AspNet.Mvc.Core/DefaultControllerPropertyActivator.cs b/src/Microsoft.AspNet.Mvc.Core/DefaultControllerPropertyActivator.cs index 44b67e9a9c..32fbc6b93a 100644 --- a/src/Microsoft.AspNet.Mvc.Core/DefaultControllerPropertyActivator.cs +++ b/src/Microsoft.AspNet.Mvc.Core/DefaultControllerPropertyActivator.cs @@ -12,12 +12,15 @@ namespace Microsoft.AspNet.Mvc { public class DefaultControllerPropertyActivator : IControllerPropertyActivator { - private readonly ConcurrentDictionary[]> _activateActions; - private readonly Func[]> _getPropertiesToActivate; + private readonly IActionBindingContextAccessor _actionBindingContextAccessor; + private readonly ConcurrentDictionary[]> _activateActions; + private readonly Func[]> _getPropertiesToActivate; - public DefaultControllerPropertyActivator() + public DefaultControllerPropertyActivator(IActionBindingContextAccessor actionBindingContextAccessor) { - _activateActions = new ConcurrentDictionary[]>(); + _actionBindingContextAccessor = actionBindingContextAccessor; + + _activateActions = new ConcurrentDictionary[]>(); _getPropertiesToActivate = GetPropertiesToActivate; } @@ -28,34 +31,39 @@ namespace Microsoft.AspNet.Mvc controllerType, _getPropertiesToActivate); + var contexts = new Contexts() + { + ActionBindingContext = _actionBindingContextAccessor.ActionBindingContext, + ActionContext = actionContext, + }; + for (var i = 0; i < propertiesToActivate.Length; i++) { var activateInfo = propertiesToActivate[i]; - activateInfo.Activate(controller, actionContext); + activateInfo.Activate(controller, contexts); } } - private PropertyActivator[] GetPropertiesToActivate(Type type) + private PropertyActivator[] GetPropertiesToActivate(Type type) { - IEnumerable> activators; - activators = PropertyActivator.GetPropertiesToActivate( + IEnumerable> activators; + activators = PropertyActivator.GetPropertiesToActivate( type, typeof(ActionContextAttribute), - p => new PropertyActivator(p, c => c)); + p => new PropertyActivator(p, c => c.ActionContext)); - activators = activators.Concat(PropertyActivator.GetPropertiesToActivate( + activators = activators.Concat(PropertyActivator.GetPropertiesToActivate( type, typeof(ActionBindingContextAttribute), - p => new PropertyActivator(p, GetActionBindingContext))); + p => new PropertyActivator(p, c => c.ActionBindingContext))); return activators.ToArray(); } - private static ActionBindingContext GetActionBindingContext(ActionContext context) + private struct Contexts { - var serviceProvider = context.HttpContext.RequestServices; - var accessor = serviceProvider.GetRequiredService>(); - return accessor.Value; + public ActionBindingContext ActionBindingContext; + public ActionContext ActionContext; } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreServiceCollectionExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreServiceCollectionExtensions.cs index 9d65a4931f..41ff87d837 100644 --- a/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/DependencyInjection/MvcCoreServiceCollectionExtensions.cs @@ -104,8 +104,8 @@ namespace Microsoft.Framework.DependencyInjection // // Action Invoker // - // These two access per-request services - services.TryAddTransient(); + // The IActionInvokerFactory is cachable + services.TryAddSingleton(); services.TryAddEnumerable( ServiceDescriptor.Transient()); @@ -136,8 +136,9 @@ namespace Microsoft.Framework.DependencyInjection // services.TryAddSingleton(); services.TryAddSingleton(); - services.TryAddScoped(typeof(IScopedInstance<>), typeof(ScopedInstance<>)); - services.TryAddScoped(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); } private static void ConfigureDefaultServices(IServiceCollection services) diff --git a/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs index 2bb3fbcd70..7700a7c6d3 100644 --- a/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs +++ b/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc.Core private readonly IReadOnlyList _outputFormatters; private readonly IReadOnlyList _modelValidatorProviders; private readonly IReadOnlyList _valueProviderFactories; - private readonly IScopedInstance _actionBindingContextAccessor; + private readonly IActionBindingContextAccessor _actionBindingContextAccessor; private readonly ILogger _logger; private readonly int _maxModelValidationErrors; @@ -61,8 +61,8 @@ namespace Microsoft.AspNet.Mvc.Core [NotNull] IReadOnlyList modelBinders, [NotNull] IReadOnlyList modelValidatorProviders, [NotNull] IReadOnlyList valueProviderFactories, - [NotNull] IScopedInstance actionBindingContextAccessor, - [NotNull] ILoggerFactory loggerFactory, + [NotNull] IActionBindingContextAccessor actionBindingContextAccessor, + [NotNull] ILogger logger, int maxModelValidationErrors) { ActionContext = actionContext; @@ -74,7 +74,7 @@ namespace Microsoft.AspNet.Mvc.Core _modelValidatorProviders = modelValidatorProviders; _valueProviderFactories = valueProviderFactories; _actionBindingContextAccessor = actionBindingContextAccessor; - _logger = loggerFactory.CreateLogger(); + _logger = logger; _maxModelValidationErrors = maxModelValidationErrors; } @@ -84,11 +84,11 @@ namespace Microsoft.AspNet.Mvc.Core { get { - return _actionBindingContextAccessor.Value; + return _actionBindingContextAccessor.ActionBindingContext; } private set { - _actionBindingContextAccessor.Value = value; + _actionBindingContextAccessor.ActionBindingContext = value; } } @@ -316,7 +316,22 @@ namespace Microsoft.AspNet.Mvc.Core } else { - // We've reached the end of resource filters, so move on to exception filters. + // We've reached the end of resource filters, so move to setting up state to invoke model + // binding. + ActionBindingContext = new ActionBindingContext(); + ActionBindingContext.InputFormatters = _resourceExecutingContext.InputFormatters; + ActionBindingContext.OutputFormatters = _resourceExecutingContext.OutputFormatters; + ActionBindingContext.ModelBinder = new CompositeModelBinder(_resourceExecutingContext.ModelBinders); + ActionBindingContext.ValidatorProvider = new CompositeModelValidatorProvider( + _resourceExecutingContext.ValidatorProviders); + + var valueProviderFactoryContext = new ValueProviderFactoryContext( + ActionContext.HttpContext, + ActionContext.RouteData.Values); + + ActionBindingContext.ValueProvider = CompositeValueProvider.Create( + _resourceExecutingContext.ValueProviderFactories, + valueProviderFactoryContext); // >> ExceptionFilters >> Model Binding >> ActionFilters >> Action await InvokeAllExceptionFiltersAsync(); @@ -465,23 +480,6 @@ namespace Microsoft.AspNet.Mvc.Core { _cursor.SetStage(FilterStage.ActionFilters); - Debug.Assert(_resourceExecutingContext != null); - - ActionBindingContext = new ActionBindingContext(); - ActionBindingContext.InputFormatters = _resourceExecutingContext.InputFormatters; - ActionBindingContext.OutputFormatters = _resourceExecutingContext.OutputFormatters; - ActionBindingContext.ModelBinder = new CompositeModelBinder(_resourceExecutingContext.ModelBinders); - ActionBindingContext.ValidatorProvider = new CompositeModelValidatorProvider( - _resourceExecutingContext.ValidatorProviders); - - var valueProviderFactoryContext = new ValueProviderFactoryContext( - ActionContext.HttpContext, - ActionContext.RouteData.Values); - - ActionBindingContext.ValueProvider = CompositeValueProvider.Create( - _resourceExecutingContext.ValueProviderFactories, - valueProviderFactoryContext); - Instance = CreateInstance(); var arguments = await BindActionArgumentsAsync(ActionContext, ActionBindingContext); diff --git a/src/Microsoft.AspNet.Mvc.Core/FormatFilter.cs b/src/Microsoft.AspNet.Mvc.Core/FormatFilter.cs index e519f4bb11..374a4c0232 100644 --- a/src/Microsoft.AspNet.Mvc.Core/FormatFilter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/FormatFilter.cs @@ -21,11 +21,11 @@ namespace Microsoft.AspNet.Mvc /// Initializes an instance of . /// /// The - /// The - public FormatFilter(IOptions options, IScopedInstance actionContext) + /// The + public FormatFilter(IOptions options, IActionContextAccessor actionContextAccessor) { IsActive = true; - Format = GetFormat(actionContext.Value); + Format = GetFormat(actionContextAccessor.ActionContext); if (string.IsNullOrEmpty(Format)) { diff --git a/src/Microsoft.AspNet.Mvc.Core/IActionBindingContextAccessor.cs b/src/Microsoft.AspNet.Mvc.Core/IActionBindingContextAccessor.cs new file mode 100644 index 0000000000..a2ade26c90 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/IActionBindingContextAccessor.cs @@ -0,0 +1,10 @@ +// 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 +{ + public interface IActionBindingContextAccessor + { + ActionBindingContext ActionBindingContext { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/IActionContextAccessor.cs b/src/Microsoft.AspNet.Mvc.Core/IActionContextAccessor.cs new file mode 100644 index 0000000000..ef4cc85cb6 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/IActionContextAccessor.cs @@ -0,0 +1,10 @@ +// 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 +{ + public interface IActionContextAccessor + { + ActionContext ActionContext { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/IScopedInstance.cs b/src/Microsoft.AspNet.Mvc.Core/IScopedInstance.cs deleted file mode 100644 index a8b57a81f8..0000000000 --- a/src/Microsoft.AspNet.Mvc.Core/IScopedInstance.cs +++ /dev/null @@ -1,12 +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 -{ - public interface IScopedInstance : IDisposable - { - TValue Value { get; set; } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/MvcRouteHandler.cs b/src/Microsoft.AspNet.Mvc.Core/MvcRouteHandler.cs index b761f1a59a..488e2c7cc6 100644 --- a/src/Microsoft.AspNet.Mvc.Core/MvcRouteHandler.cs +++ b/src/Microsoft.AspNet.Mvc.Core/MvcRouteHandler.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Diagnostics; using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.Core; @@ -17,15 +16,19 @@ namespace Microsoft.AspNet.Mvc { public class MvcRouteHandler : IRouter { - private INotifier _notifier; + private IActionContextAccessor _actionContextAccessor; + private IActionInvokerFactory _actionInvokerFactory; + private IActionSelector _actionSelector; private ILogger _logger; + private INotifier _notifier; public VirtualPathData GetVirtualPath([NotNull] VirtualPathContext context) { + EnsureServices(context.Context); + // The contract of this method is to check that the values coming in from the route are valid; // that they match an existing action, setting IsBound = true if the values are OK. - var actionSelector = context.Context.RequestServices.GetRequiredService(); - context.IsBound = actionSelector.HasValidAction(context); + context.IsBound = _actionSelector.HasValidAction(context); // We return null here because we're not responsible for generating the url, the route is. return null; @@ -38,13 +41,9 @@ namespace Microsoft.AspNet.Mvc // Verify if AddMvc was done before calling UseMvc // We use the MvcMarkerService to make sure if all the services were added. MvcServicesHelper.ThrowIfMvcNotRegistered(services); + EnsureServices(context.HttpContext); - EnsureLogger(context.HttpContext); - EnsureNotifier(context.HttpContext); - - var actionSelector = services.GetRequiredService(); - var actionDescriptor = await actionSelector.SelectAsync(context); - + var actionDescriptor = await _actionSelector.SelectAsync(context); if (actionDescriptor == null) { _logger.LogVerbose("No actions matched the current request."); @@ -104,15 +103,10 @@ namespace Microsoft.AspNet.Mvc private async Task InvokeActionAsync(RouteContext context, ActionDescriptor actionDescriptor) { - var services = context.HttpContext.RequestServices; - Debug.Assert(services != null); - var actionContext = new ActionContext(context.HttpContext, context.RouteData, actionDescriptor); - - var contextAccessor = services.GetRequiredService>(); - contextAccessor.Value = actionContext; - var invokerFactory = services.GetRequiredService(); - var invoker = invokerFactory.CreateInvoker(actionContext); + _actionContextAccessor.ActionContext = actionContext; + + var invoker = _actionInvokerFactory.CreateInvoker(actionContext); if (invoker == null) { throw new InvalidOperationException( @@ -123,17 +117,29 @@ namespace Microsoft.AspNet.Mvc await invoker.InvokeAsync(); } - private void EnsureLogger(HttpContext context) + private void EnsureServices(HttpContext context) { + if (_actionContextAccessor == null) + { + _actionContextAccessor = context.RequestServices.GetRequiredService(); + } + + if (_actionInvokerFactory == null) + { + _actionInvokerFactory = context.RequestServices.GetRequiredService(); + } + + if (_actionSelector == null) + { + _actionSelector = context.RequestServices.GetRequiredService(); + } + if (_logger == null) { var factory = context.RequestServices.GetRequiredService(); _logger = factory.CreateLogger(); } - } - private void EnsureNotifier(HttpContext context) - { if (_notifier == null) { _notifier = context.RequestServices.GetRequiredService(); diff --git a/src/Microsoft.AspNet.Mvc.Core/ObjectResult.cs b/src/Microsoft.AspNet.Mvc.Core/ObjectResult.cs index 061f381c1a..84aae59641 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ObjectResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ObjectResult.cs @@ -297,8 +297,8 @@ namespace Microsoft.AspNet.Mvc var actionBindingContext = context .HttpContext .RequestServices - .GetRequiredService>() - .Value; + .GetRequiredService() + .ActionBindingContext; // In scenarios where there is a resource filter which directly shortcircuits using an ObjectResult. // actionBindingContext is not setup yet and is null. diff --git a/src/Microsoft.AspNet.Mvc.Core/ScopedInstance.cs b/src/Microsoft.AspNet.Mvc.Core/ScopedInstance.cs deleted file mode 100644 index 0ed1e21e3c..0000000000 --- a/src/Microsoft.AspNet.Mvc.Core/ScopedInstance.cs +++ /dev/null @@ -1,21 +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 -{ - public class ScopedInstance : IScopedInstance - { - public T Value { get; set; } - - public void Dispose() - { - var disposable = Value as IDisposable; - if (disposable != null) - { - disposable.Dispose(); - } - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/UrlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/UrlHelper.cs index 97ed3e0096..b379f9f10e 100644 --- a/src/Microsoft.AspNet.Mvc.Core/UrlHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/UrlHelper.cs @@ -7,7 +7,6 @@ using System.Diagnostics; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.Internal; using Microsoft.AspNet.Routing; -using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc @@ -18,28 +17,32 @@ namespace Microsoft.AspNet.Mvc /// public class UrlHelper : IUrlHelper { - private readonly HttpContext _httpContext; - private readonly IRouter _router; - private readonly IDictionary _ambientValues; + private readonly IActionContextAccessor _actionContextAccessor; private readonly IActionSelector _actionSelector; /// /// Initializes a new instance of the class using the specified action context and /// action selector. /// - /// The to access the action context + /// The to access the action context /// of the current request. /// The to be used for verifying the correctness of /// supplied parameters for a route. /// - public UrlHelper(IScopedInstance contextAccessor, IActionSelector actionSelector) + public UrlHelper(IActionContextAccessor actionContextAccessor, IActionSelector actionSelector) { - _httpContext = contextAccessor.Value.HttpContext; - _router = contextAccessor.Value.RouteData.Routers[0]; - _ambientValues = contextAccessor.Value.RouteData.Values; + _actionContextAccessor = actionContextAccessor; _actionSelector = actionSelector; } + protected IDictionary AmbientValues => ActionContext.RouteData.Values; + + protected ActionContext ActionContext => _actionContextAccessor.ActionContext; + + protected HttpContext HttpContext => ActionContext.HttpContext; + + protected IRouter Router => ActionContext.RouteData.Routers[0]; + /// public virtual string Action(UrlActionContext actionContext) { @@ -98,8 +101,8 @@ namespace Microsoft.AspNet.Mvc /// The absolute path of the URL. protected virtual string GeneratePathFromRoute(string routeName, IDictionary values) { - var context = new VirtualPathContext(_httpContext, _ambientValues, values, routeName); - var pathData = _router.GetVirtualPath(context); + var context = new VirtualPathContext(HttpContext, AmbientValues, values, routeName); + var pathData = Router.GetVirtualPath(context); if (pathData == null) { return null; @@ -108,7 +111,7 @@ namespace Microsoft.AspNet.Mvc // VirtualPathData.VirtualPath returns string.Empty for null. Debug.Assert(pathData.VirtualPath != null); - var fullPath = _httpContext.Request.PathBase.Add(pathData.VirtualPath).Value; + var fullPath = HttpContext.Request.PathBase.Add(pathData.VirtualPath).Value; if (fullPath.Length == 0) { return "/"; @@ -129,7 +132,7 @@ namespace Microsoft.AspNet.Mvc else if (contentPath[0] == '~') { var segment = new PathString(contentPath.Substring(1)); - var applicationPath = _httpContext.Request.PathBase; + var applicationPath = HttpContext.Request.PathBase; return applicationPath.Add(segment).Value; } @@ -144,8 +147,8 @@ namespace Microsoft.AspNet.Mvc { RouteName = routeName, Values = values, - Protocol = _httpContext.Request.Scheme, - Host = _httpContext.Request.Host.ToUriComponent() + Protocol = HttpContext.Request.Scheme, + Host = HttpContext.Request.Host.ToUriComponent() }); } @@ -174,7 +177,7 @@ namespace Microsoft.AspNet.Mvc else { protocol = string.IsNullOrEmpty(protocol) ? "http" : protocol; - host = string.IsNullOrEmpty(host) ? _httpContext.Request.Host.Value : host; + host = string.IsNullOrEmpty(host) ? HttpContext.Request.Host.Value : host; url = protocol + "://" + host + url; return url; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerActionInvokerTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerActionInvokerTest.cs index 263901f481..577dae6013 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerActionInvokerTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerActionInvokerTest.cs @@ -2040,8 +2040,8 @@ namespace Microsoft.AspNet.Mvc new IModelBinder[0], new IModelValidatorProvider[0], new IValueProviderFactory[0], - new MockScopedInstance(), - new NullLoggerFactory(), + new ActionBindingContextAccessor(), + new NullLoggerFactory().CreateLogger(), maxAllowedErrorsInModelState); return invoker; @@ -2102,8 +2102,8 @@ namespace Microsoft.AspNet.Mvc new IModelBinder[] { binder.Object }, new IModelValidatorProvider[0], new IValueProviderFactory[0], - new MockScopedInstance(), - new NullLoggerFactory(), + new ActionBindingContextAccessor(), + new NullLoggerFactory().CreateLogger(), 200); // Act @@ -2202,8 +2202,8 @@ namespace Microsoft.AspNet.Mvc IReadOnlyList modelBinders, IReadOnlyList modelValidatorProviders, IReadOnlyList valueProviderFactories, - IScopedInstance actionBindingContext, - ILoggerFactory loggerFactory, + IActionBindingContextAccessor actionBindingContext, + ILogger logger, int maxAllowedErrorsInModelState) : base( actionContext, @@ -2217,7 +2217,7 @@ namespace Microsoft.AspNet.Mvc modelValidatorProviders, valueProviderFactories, actionBindingContext, - loggerFactory, + logger, maxAllowedErrorsInModelState) { ControllerFactory = controllerFactory; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/CreatedAtActionResultTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/CreatedAtActionResultTests.cs index 27d1f27102..5d2da109ac 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/CreatedAtActionResultTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/CreatedAtActionResultTests.cs @@ -102,13 +102,12 @@ namespace Microsoft.AspNet.Mvc services.Setup(s => s.GetService(typeof(ILogger))) .Returns(new Mock>().Object); - var mockContextAccessor = new Mock>(); - mockContextAccessor - .SetupGet(o => o.Value) - .Returns(new ActionBindingContext() { OutputFormatters = optionsAccessor.Options.OutputFormatters }); - - services.Setup(o => o.GetService(typeof(IScopedInstance))) - .Returns(mockContextAccessor.Object); + var actionBindingContext = new ActionBindingContext + { + OutputFormatters = optionsAccessor.Options.OutputFormatters + }; + services.Setup(o => o.GetService(typeof(IActionBindingContextAccessor))) + .Returns(new ActionBindingContextAccessor() { ActionBindingContext = actionBindingContext }); return httpContext; } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/CreatedAtRouteResultTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/CreatedAtRouteResultTests.cs index a53ed5a47d..cec3d740ac 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/CreatedAtRouteResultTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/CreatedAtRouteResultTests.cs @@ -110,14 +110,8 @@ namespace Microsoft.AspNet.Mvc httpContext.Setup(o => o.Response) .Returns(response); - - var mockContextAccessor = new Mock>(); - mockContextAccessor - .SetupGet(o => o.Value) - .Returns((ActionBindingContext)null); - - httpContext.Setup(o => o.RequestServices.GetService(typeof(IScopedInstance))) - .Returns(mockContextAccessor.Object); + httpContext.Setup(o => o.RequestServices.GetService(typeof(IActionBindingContextAccessor))) + .Returns(new ActionBindingContextAccessor()); return httpContext.Object; } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/CreatedResultTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/CreatedResultTests.cs index 257e2408c0..7b556a8838 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/CreatedResultTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/CreatedResultTests.cs @@ -97,13 +97,13 @@ namespace Microsoft.AspNet.Mvc .Setup(p => p.RequestServices.GetService(typeof(ILogger))) .Returns(new Mock>().Object); - var mockActionBindingContext = new Mock>(); - mockActionBindingContext - .SetupGet(o=> o.Value) - .Returns(new ActionBindingContext() { OutputFormatters = optionsAccessor.Options.OutputFormatters }); + var actionBindingContext = new ActionBindingContext() + { + OutputFormatters = optionsAccessor.Options.OutputFormatters + }; httpContext - .Setup(o => o.RequestServices.GetService(typeof(IScopedInstance))) - .Returns(mockActionBindingContext.Object); + .Setup(o => o.RequestServices.GetService(typeof(IActionBindingContextAccessor))) + .Returns(new ActionBindingContextAccessor() { ActionBindingContext = actionBindingContext }); return httpContext.Object; } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerFactoryTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerFactoryTest.cs index 06e3083ddc..593795cff0 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerFactoryTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerFactoryTest.cs @@ -102,7 +102,7 @@ namespace Microsoft.AspNet.Mvc.Core var bindingContext = new ActionBindingContext(); var services = GetServices(); - services.GetRequiredService>().Value = bindingContext; + services.GetRequiredService().ActionBindingContext = bindingContext; var httpContext = new DefaultHttpContext { RequestServices = services @@ -255,11 +255,10 @@ namespace Microsoft.AspNet.Mvc.Core .Returns(metadataProvider); services.Setup(s => s.GetService(typeof(IObjectModelValidator))) .Returns(new DefaultObjectValidator(new IExcludeTypeValidationFilter[0], metadataProvider)); - services - .Setup(s => s.GetService(typeof(IScopedInstance))) - .Returns(new MockScopedInstance()); services.Setup(s => s.GetService(typeof(ITempDataDictionary))) .Returns(new Mock().Object); + services.Setup(s => s.GetService(typeof(IActionBindingContextAccessor))) + .Returns(new ActionBindingContextAccessor()); return services.Object; } @@ -268,7 +267,7 @@ namespace Microsoft.AspNet.Mvc.Core controllerActivator = controllerActivator ?? Mock.Of(); var propertyActivators = new IControllerPropertyActivator[] { - new DefaultControllerPropertyActivator(), + new DefaultControllerPropertyActivator(new ActionBindingContextAccessor()), }; return new DefaultControllerFactory(controllerActivator, propertyActivators); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/FormatFilterTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/FormatFilterTest.cs index ccf368e8be..5f855d6c3a 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/FormatFilterTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/FormatFilterTest.cs @@ -43,7 +43,7 @@ namespace Microsoft.AspNet.Mvc var resultExecutingContext = mockObjects.CreateResultExecutingContext(); var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilterMetadata[] { }); - var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ScopedInstance); + var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ActionContextAccessor); // Act filter.OnResourceExecuting(resourceExecutingContext); @@ -90,7 +90,7 @@ namespace Microsoft.AspNet.Mvc ac, new IFilterMetadata[] { }); - var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ScopedInstance); + var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ActionContextAccessor); // Act filter.OnResourceExecuting(resourceExecutingContext); @@ -122,7 +122,7 @@ namespace Microsoft.AspNet.Mvc format, MediaTypeHeaderValue.Parse(contentType)); - var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ScopedInstance); + var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ActionContextAccessor); // Act filter.OnResourceExecuting(resourceExecutingContext); @@ -145,7 +145,7 @@ namespace Microsoft.AspNet.Mvc var mockObjects = new MockObjects(format, place); var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilterMetadata[] { }); - var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ScopedInstance); + var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ActionContextAccessor); // Act filter.OnResourceExecuting(resourceExecutingContext); @@ -162,7 +162,7 @@ namespace Microsoft.AspNet.Mvc var mockObjects = new MockObjects(); var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilterMetadata[] { }); - var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ScopedInstance); + var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ActionContextAccessor); // Act filter.OnResourceExecuting(resourceExecutingContext); @@ -184,7 +184,7 @@ namespace Microsoft.AspNet.Mvc var mockObjects = new MockObjects(format, place); var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilterMetadata[] { produces }); - var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ScopedInstance); + var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ActionContextAccessor); // Act filter.OnResourceExecuting(resourceExecutingContext); @@ -205,7 +205,7 @@ namespace Microsoft.AspNet.Mvc "xml", MediaTypeHeaderValue.Parse("application/xml")); - var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ScopedInstance); + var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ActionContextAccessor); // Act filter.OnResourceExecuting(resourceExecutingContext); @@ -226,7 +226,7 @@ namespace Microsoft.AspNet.Mvc "xml", MediaTypeHeaderValue.Parse("application/xml;version=1")); - var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ScopedInstance); + var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ActionContextAccessor); // Act filter.OnResourceExecuting(resourceExecutingContext); @@ -252,7 +252,7 @@ namespace Microsoft.AspNet.Mvc "xml", MediaTypeHeaderValue.Parse("application/xml")); - var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ScopedInstance); + var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ActionContextAccessor); // Act filter.OnResourceExecuting(resourceExecutingContext); @@ -271,7 +271,7 @@ namespace Microsoft.AspNet.Mvc // Arrange var mockObjects = new MockObjects(format, place); var resourceExecutingContext = mockObjects.CreateResourceExecutingContext(new IFilterMetadata[] { }); - var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ScopedInstance); + var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ActionContextAccessor); // Act filter.OnResourceExecuting(resourceExecutingContext); @@ -294,7 +294,7 @@ namespace Microsoft.AspNet.Mvc var mockObjects = new MockObjects(format, place); var resultExecutingContext = mockObjects.CreateResultExecutingContext(); var filterAttribute = new FormatFilterAttribute(); - var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ScopedInstance); + var filter = new FormatFilter(mockObjects.OptionsManager, mockObjects.ActionContextAccessor); // Act and Assert Assert.Equal(expected, filter.IsActive); @@ -322,7 +322,7 @@ namespace Microsoft.AspNet.Mvc public HttpContext MockHttpContext { get; private set; } public ActionContext MockActionContext { get; private set; } - public IScopedInstance ScopedInstance { get; private set; } + public IActionContextAccessor ActionContextAccessor { get; private set; } public IOptions OptionsManager { get; private set; } public MockObjects(string format = null, FormatSource? place = null) @@ -399,9 +399,10 @@ namespace Microsoft.AspNet.Mvc // Setup MVC services on mock service provider MockActionContext = CreateMockActionContext(httpContext, format, place); - var scopedInstance = new Mock>(); - scopedInstance.Setup(s => s.Value).Returns(MockActionContext); - ScopedInstance = scopedInstance.Object; + ActionContextAccessor = new ActionContextAccessor() + { + ActionContext = MockActionContext, + }; } } #endif diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/HttpNotFoundObjectResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/HttpNotFoundObjectResultTest.cs index 8f6c7f15a4..85f7930b55 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/HttpNotFoundObjectResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/HttpNotFoundObjectResultTest.cs @@ -91,16 +91,16 @@ namespace Microsoft.AspNet.Mvc optionsAccessor.Options.OutputFormatters.Add(new StringOutputFormatter()); optionsAccessor.Options.OutputFormatters.Add(new JsonOutputFormatter()); optionsAccessor.Options.RespectBrowserAcceptHeader = respectBrowserAcceptHeader; - var mockContextAccessor = new Mock>(); - mockContextAccessor - .SetupGet(o => o.Value) - .Returns(new ActionBindingContext() + var actionBindingContextAccessor = new ActionBindingContextAccessor() + { + ActionBindingContext = new ActionBindingContext() { OutputFormatters = optionsAccessor.Options.OutputFormatters - }); + } + }; - httpContext.Setup(o => o.RequestServices.GetService(typeof(IScopedInstance))) - .Returns(mockContextAccessor.Object); + httpContext.Setup(o => o.RequestServices.GetService(typeof(IActionBindingContextAccessor))) + .Returns(actionBindingContextAccessor); httpContext.Setup(o => o.RequestServices.GetService(typeof(IOptions))) .Returns(optionsAccessor); httpContext.Setup(o => o.RequestServices.GetService(typeof(ILogger))) diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/HttpOkObjectResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/HttpOkObjectResultTest.cs index f8e29613bf..06bed410fe 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/HttpOkObjectResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/HttpOkObjectResultTest.cs @@ -81,11 +81,11 @@ namespace Microsoft.AspNet.Mvc { OutputFormatters = optionsAccessor.Options.OutputFormatters, }; - var bindingContextAccessor = new MockScopedInstance + var bindingContextAccessor = new ActionBindingContextAccessor { - Value = bindingContext, + ActionBindingContext = bindingContext, }; - services.Add(new ServiceDescriptor(typeof(IScopedInstance), bindingContextAccessor)); + services.Add(new ServiceDescriptor(typeof(IActionBindingContextAccessor), bindingContextAccessor)); return services.BuildServiceProvider(); } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/MockScopedInstance.cs b/test/Microsoft.AspNet.Mvc.Core.Test/MockScopedInstance.cs deleted file mode 100644 index 13f1cd2ea6..0000000000 --- a/test/Microsoft.AspNet.Mvc.Core.Test/MockScopedInstance.cs +++ /dev/null @@ -1,16 +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 Microsoft.Framework.DependencyInjection; - -namespace Microsoft.AspNet.Mvc -{ - public class MockScopedInstance : IScopedInstance - { - public T Value { get; set; } - - public void Dispose() - { - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/BodyModelBinderTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/BodyModelBinderTests.cs index b2f5f3c0ef..451a3d48bc 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/BodyModelBinderTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/BodyModelBinderTests.cs @@ -290,25 +290,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding return bindingContext; } - private static IScopedInstance CreateActionContext(HttpContext context) - { - return CreateActionContext(context, (new Mock()).Object); - } - - private static IScopedInstance CreateActionContext(HttpContext context, IRouter router) - { - var routeData = new RouteData(); - routeData.Routers.Add(router); - - var actionContext = new ActionContext(context, - routeData, - new ActionDescriptor()); - var contextAccessor = new Mock>(); - contextAccessor.SetupGet(c => c.Value) - .Returns(actionContext); - return contextAccessor.Object; - } - private class Person { public string Name { get; set; } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/MvcRouteHandlerTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/MvcRouteHandlerTests.cs index 56703aafda..088820ea5f 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/MvcRouteHandlerTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/MvcRouteHandlerTests.cs @@ -205,8 +205,6 @@ namespace Microsoft.AspNet.Mvc IOptions optionsAccessor = null, object notificationListener = null) { - var mockContextAccessor = new Mock>(); - if (actionDescriptor == null) { var mockAction = new Mock(); @@ -252,8 +250,8 @@ namespace Microsoft.AspNet.Mvc } var httpContext = new Mock(); - httpContext.Setup(h => h.RequestServices.GetService(typeof(IScopedInstance))) - .Returns(mockContextAccessor.Object); + httpContext.Setup(h => h.RequestServices.GetService(typeof(IActionContextAccessor))) + .Returns(new ActionContextAccessor()); httpContext.Setup(h => h.RequestServices.GetService(typeof(IActionSelector))) .Returns(actionSelector); httpContext.Setup(h => h.RequestServices.GetService(typeof(IActionInvokerFactory))) diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ObjectResultTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ObjectResultTests.cs index 3629472dee..10d5cb2d38 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ObjectResultTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ObjectResultTests.cs @@ -904,20 +904,14 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults httpContext.Setup(o => o.RequestServices.GetService(typeof(ILogger))) .Returns(new Mock>().Object); - var mockActionBindingContext = new Mock>(); - - ActionBindingContext bindingContext = null; + ActionBindingContext actionBindingContext = null; if (setupActionBindingContext) { - bindingContext = new ActionBindingContext { OutputFormatters = outputFormatters.ToList() }; + actionBindingContext = new ActionBindingContext { OutputFormatters = outputFormatters.ToList() }; } - - mockActionBindingContext - .SetupGet(o => o.Value) - .Returns(bindingContext); - - httpContext.Setup(o => o.RequestServices.GetService(typeof(IScopedInstance))) - .Returns(mockActionBindingContext.Object); + + httpContext.Setup(o => o.RequestServices.GetService(typeof(IActionBindingContextAccessor))) + .Returns(new ActionBindingContextAccessor() { ActionBindingContext = actionBindingContext }); return new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor()); } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/RedirectResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/RedirectResultTest.cs index 4392eab04b..27baa166cd 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/RedirectResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/RedirectResultTest.cs @@ -115,10 +115,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test { var httpContext = new Mock(); var actionContext = GetActionContext(httpContext.Object); - var mockContentAccessor = new Mock>(); - mockContentAccessor.SetupGet(o => o.Value).Returns(actionContext); + var actionContextAccessor = new ActionContextAccessor() { ActionContext = actionContext }; var mockActionSelector = new Mock(); - var urlHelper = new UrlHelper(mockContentAccessor.Object, mockActionSelector.Object); + var urlHelper = new UrlHelper(actionContextAccessor, mockActionSelector.Object); var serviceProvider = GetServiceProvider(urlHelper); httpContext.Setup(o => o.Response) diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ScopedInstanceTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ScopedInstanceTest.cs deleted file mode 100644 index a502cde440..0000000000 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ScopedInstanceTest.cs +++ /dev/null @@ -1,68 +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 Xunit; - -namespace Microsoft.AspNet.Mvc -{ - public class ScopedInstanceTest - { - [Fact] - public void ScopedInstanceDisposesIDisposables() - { - var disposable = new Disposable(); - - // Arrange - var scopedInstance = new ScopedInstance - { - Value = disposable, - }; - - // Act - scopedInstance.Dispose(); - - // Assert - Assert.True(disposable.IsDisposed); - } - - [Fact] - public void ScopedInstanceDoesNotThrowOnNonIDisposable() - { - // Arrange - var scopedInstance = new ScopedInstance() - { - Value = new object(), - }; - - // Act - scopedInstance.Dispose(); - } - - [Fact] - public void ScopedInstanceDoesNotThrowOnNull() - { - // Arrange - var scopedInstance = new ScopedInstance() - { - Value = null, // just making it explicit that there is not value set yet. - }; - - // Act - scopedInstance.Dispose(); - - // Assert - Assert.Null(scopedInstance.Value); - } - - private class Disposable : IDisposable - { - public bool IsDisposed { get; set; } - - public void Dispose() - { - IsDisposed = true; - } - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/UrlHelperTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/UrlHelperTest.cs index 9794c8e971..1a3b718915 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/UrlHelperTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/UrlHelperTest.cs @@ -820,23 +820,18 @@ namespace Microsoft.AspNet.Mvc return context; } - private static IScopedInstance CreateActionContext(HttpContext context) + private static IActionContextAccessor CreateActionContext(HttpContext context) { return CreateActionContext(context, (new Mock()).Object); } - private static IScopedInstance CreateActionContext(HttpContext context, IRouter router) + private static IActionContextAccessor CreateActionContext(HttpContext context, IRouter router) { var routeData = new RouteData(); routeData.Routers.Add(router); - var actionContext = new ActionContext(context, - routeData, - new ActionDescriptor()); - var contextAccessor = new Mock>(); - contextAccessor.SetupGet(c => c.Value) - .Returns(actionContext); - return contextAccessor.Object; + var actionContext = new ActionContext(context, routeData, new ActionDescriptor()); + return new ActionContextAccessor() { ActionContext = actionContext }; } private static UrlHelper CreateUrlHelper() @@ -874,7 +869,7 @@ namespace Microsoft.AspNet.Mvc return new UrlHelper(actionContext, actionSelector.Object); } - private static UrlHelper CreateUrlHelper(IScopedInstance contextAccessor) + private static UrlHelper CreateUrlHelper(IActionContextAccessor contextAccessor) { var actionSelector = new Mock(MockBehavior.Strict); return new UrlHelper(contextAccessor, actionSelector.Object); diff --git a/test/Microsoft.AspNet.Mvc.IntegrationTests/ModelBindingTestHelper.cs b/test/Microsoft.AspNet.Mvc.IntegrationTests/ModelBindingTestHelper.cs index 65ec766e19..a7fe7139e4 100644 --- a/test/Microsoft.AspNet.Mvc.IntegrationTests/ModelBindingTestHelper.cs +++ b/test/Microsoft.AspNet.Mvc.IntegrationTests/ModelBindingTestHelper.cs @@ -35,7 +35,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests var httpContext = GetHttpContext(updateRequest, updateOptions); var services = httpContext.RequestServices; - var actionBindingContext = services.GetRequiredService>().Value; + var actionBindingContext = services.GetRequiredService().ActionBindingContext; return new OperationBindingContext() { @@ -77,8 +77,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests var actionContext = new ActionContext(httpContext, new RouteData(), new ControllerActionDescriptor()); var actionContextAccessor = - httpContext.RequestServices.GetRequiredService>(); - actionContextAccessor.Value = actionContext; + httpContext.RequestServices.GetRequiredService(); + actionContextAccessor.ActionContext = actionContext; var options = new TestMvcOptions().Options; if (updateOptions != null) @@ -87,8 +87,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests } var actionBindingContextAccessor = - httpContext.RequestServices.GetRequiredService>(); - actionBindingContextAccessor.Value = GetActionBindingContext(options, actionContext); + httpContext.RequestServices.GetRequiredService(); + actionBindingContextAccessor.ActionBindingContext = GetActionBindingContext(options, actionContext); } private static ActionBindingContext GetActionBindingContext(MvcOptions options, ActionContext actionContext) diff --git a/test/Microsoft.AspNet.Mvc.IntegrationTests/MutableObjectModelBinderIntegrationTest.cs b/test/Microsoft.AspNet.Mvc.IntegrationTests/MutableObjectModelBinderIntegrationTest.cs index 07fa780584..f107438e27 100644 --- a/test/Microsoft.AspNet.Mvc.IntegrationTests/MutableObjectModelBinderIntegrationTest.cs +++ b/test/Microsoft.AspNet.Mvc.IntegrationTests/MutableObjectModelBinderIntegrationTest.cs @@ -272,7 +272,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests public string Name { get; set; } [FromServices] - public IScopedInstance BindingContext { get; set; } + public IActionBindingContextAccessor BindingContext { get; set; } } [Fact] @@ -1528,7 +1528,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests public Address1 Address { get; set; } [FromServices] - public IScopedInstance BindingContext { get; set; } + public IActionBindingContextAccessor BindingContext { get; set; } } // If a nested POCO object has all properties bound from a greedy source, then it should be populated diff --git a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/RemoteAttributeTest.cs b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/RemoteAttributeTest.cs index 8d6f8ae022..75a87abcc0 100644 --- a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/RemoteAttributeTest.cs +++ b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/RemoteAttributeTest.cs @@ -536,7 +536,7 @@ namespace Microsoft.AspNet.Mvc return builder; } - private static IScopedInstance GetContextAccessor( + private static IActionContextAccessor GetContextAccessor( IServiceProvider serviceProvider, RouteData routeData = null) { @@ -557,12 +557,12 @@ namespace Microsoft.AspNet.Mvc } var actionContext = new ActionContext(httpContext, routeData, new ActionDescriptor()); - var contextAccessor = new Mock>(); - contextAccessor - .SetupGet(accessor => accessor.Value) - .Returns(actionContext); + var contextAccessor = new ActionContextAccessor() + { + ActionContext = actionContext, + }; - return contextAccessor.Object; + return contextAccessor; } private static ServiceCollection GetServiceCollection() diff --git a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/BadRequestErrorMessageResultTest.cs b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/BadRequestErrorMessageResultTest.cs index a85486005e..33d4c21ba2 100644 --- a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/BadRequestErrorMessageResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/BadRequestErrorMessageResultTest.cs @@ -72,15 +72,10 @@ namespace System.Web.Http var optionsAccessor = new Mock>(); optionsAccessor.SetupGet(o => o.Options) .Returns(options); - - var mockActionBindingContext = new Mock>(); - var bindingContext = new ActionBindingContext { OutputFormatters = options.OutputFormatters }; - mockActionBindingContext - .SetupGet(o => o.Value) - .Returns(bindingContext); - - services.Setup(o => o.GetService(typeof(IScopedInstance))) - .Returns(mockActionBindingContext.Object); + + var actionBindingContext = new ActionBindingContext { OutputFormatters = options.OutputFormatters }; + services.Setup(o => o.GetService(typeof(IActionBindingContextAccessor))) + .Returns(new ActionBindingContextAccessor() { ActionBindingContext = actionBindingContext }); services.Setup(s => s.GetService(typeof(IOptions))) .Returns(optionsAccessor.Object); diff --git a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/ExceptionResultTest.cs b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/ExceptionResultTest.cs index 950c74d48b..bb81c934d0 100644 --- a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/ExceptionResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/ExceptionResultTest.cs @@ -73,14 +73,9 @@ namespace System.Web.Http optionsAccessor.SetupGet(o => o.Options) .Returns(options); - var mockActionBindingContext = new Mock>(); - var bindingContext = new ActionBindingContext { OutputFormatters = options.OutputFormatters }; - mockActionBindingContext - .SetupGet(o => o.Value) - .Returns(bindingContext); - - services.Setup(o => o.GetService(typeof(IScopedInstance))) - .Returns(mockActionBindingContext.Object); + var actionBindingContext = new ActionBindingContext { OutputFormatters = options.OutputFormatters }; + services.Setup(o => o.GetService(typeof(IActionBindingContextAccessor))) + .Returns(new ActionBindingContextAccessor() { ActionBindingContext = actionBindingContext }); services.Setup(s => s.GetService(typeof(IOptions))) .Returns(optionsAccessor.Object); diff --git a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/InvalidModelStateResultTest.cs b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/InvalidModelStateResultTest.cs index b50453f498..96ef43adf0 100644 --- a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/InvalidModelStateResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/InvalidModelStateResultTest.cs @@ -86,15 +86,9 @@ namespace System.Web.Http optionsAccessor.SetupGet(o => o.Options) .Returns(options); - var mockActionBindingContext = new Mock>(); - - var bindingContext = new ActionBindingContext { OutputFormatters = options.OutputFormatters }; - mockActionBindingContext - .SetupGet(o => o.Value) - .Returns(bindingContext); - - services.Setup(o => o.GetService(typeof(IScopedInstance))) - .Returns(mockActionBindingContext.Object); + var actionBindingContext = new ActionBindingContext { OutputFormatters = options.OutputFormatters }; + services.Setup(o => o.GetService(typeof(IActionBindingContextAccessor))) + .Returns(new ActionBindingContextAccessor() { ActionBindingContext = actionBindingContext }); services.Setup(s => s.GetService(typeof(IOptions))) .Returns(optionsAccessor.Object); diff --git a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/NegotiatedContentResultTest.cs b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/NegotiatedContentResultTest.cs index acefd3435e..8d2ace76c8 100644 --- a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/NegotiatedContentResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/NegotiatedContentResultTest.cs @@ -74,14 +74,9 @@ namespace System.Web.Http optionsAccessor.SetupGet(o => o.Options) .Returns(options); - var mockActionBindingContext = new Mock>(); - var bindingContext = new ActionBindingContext { OutputFormatters = options.OutputFormatters }; - mockActionBindingContext - .SetupGet(o => o.Value) - .Returns(bindingContext); - - services.Setup(o => o.GetService(typeof(IScopedInstance))) - .Returns(mockActionBindingContext.Object); + var actionBindingContext = new ActionBindingContext { OutputFormatters = options.OutputFormatters }; + services.Setup(o => o.GetService(typeof(IActionBindingContextAccessor))) + .Returns(new ActionBindingContextAccessor() { ActionBindingContext = actionBindingContext }); services.Setup(s => s.GetService(typeof(IOptions))) .Returns(optionsAccessor.Object); diff --git a/test/WebSites/RoutingWebSite/TestResponseGenerator.cs b/test/WebSites/RoutingWebSite/TestResponseGenerator.cs index 26a7c95d22..769f6d0f34 100644 --- a/test/WebSites/RoutingWebSite/TestResponseGenerator.cs +++ b/test/WebSites/RoutingWebSite/TestResponseGenerator.cs @@ -14,9 +14,9 @@ namespace RoutingWebSite { private readonly ActionContext _actionContext; - public TestResponseGenerator(IScopedInstance contextAccessor) + public TestResponseGenerator(IActionContextAccessor contextAccessor) { - _actionContext = contextAccessor.Value; + _actionContext = contextAccessor.ActionContext; if (_actionContext == null) { throw new InvalidOperationException("ActionContext should not be null here."); diff --git a/test/WebSites/UrlHelperWebSite/CustomUrlHelper.cs b/test/WebSites/UrlHelperWebSite/CustomUrlHelper.cs index a15796d68b..74ebffdb4e 100644 --- a/test/WebSites/UrlHelperWebSite/CustomUrlHelper.cs +++ b/test/WebSites/UrlHelperWebSite/CustomUrlHelper.cs @@ -4,7 +4,6 @@ using System; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc; -using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; namespace UrlHelperWebSite @@ -19,12 +18,14 @@ namespace UrlHelperWebSite private readonly IOptions _appOptions; private readonly HttpContext _httpContext; - public CustomUrlHelper(IScopedInstance contextAccessor, IActionSelector actionSelector, - IOptions appOptions) + public CustomUrlHelper( + IActionContextAccessor contextAccessor, + IActionSelector actionSelector, + IOptions appOptions) : base(contextAccessor, actionSelector) { _appOptions = appOptions; - _httpContext = contextAccessor.Value.HttpContext; + _httpContext = contextAccessor.ActionContext.HttpContext; } /// diff --git a/test/WebSites/VersioningWebSite/TestResponseGenerator.cs b/test/WebSites/VersioningWebSite/TestResponseGenerator.cs index 57e2521b0a..808040f235 100644 --- a/test/WebSites/VersioningWebSite/TestResponseGenerator.cs +++ b/test/WebSites/VersioningWebSite/TestResponseGenerator.cs @@ -14,9 +14,9 @@ namespace VersioningWebSite { private readonly ActionContext _actionContext; - public TestResponseGenerator(IScopedInstance contextAccessor) + public TestResponseGenerator(IActionContextAccessor contextAccessor) { - _actionContext = contextAccessor.Value; + _actionContext = contextAccessor.ActionContext; if (_actionContext == null) { throw new InvalidOperationException("ActionContext should not be null here.");