Changing when controllers are created

This change moves controller creation to the stage immediately before
model binding. The controller will be disposed/released before Resource
Filters run their 'OnResourceExecuted' method. Previously the controller's
lifetime surrounded all filter invocation.

Additionally, the Controller property is now gone from ActionContext, and
is moved to the 4 filter contexts that should have access to it
Action*Context and Result*Context.
This commit is contained in:
Ryan Nowak 2015-01-15 15:37:01 -08:00
parent e1069dbf65
commit 0c5a702245
15 changed files with 184 additions and 110 deletions

View File

@ -14,7 +14,6 @@ namespace Microsoft.AspNet.Mvc
: this(actionContext.HttpContext, actionContext.RouteData, actionContext.ActionDescriptor) : this(actionContext.HttpContext, actionContext.RouteData, actionContext.ActionDescriptor)
{ {
ModelState = actionContext.ModelState; ModelState = actionContext.ModelState;
Controller = actionContext.Controller;
} }
public ActionContext([NotNull] RouteContext routeContext, [NotNull] ActionDescriptor actionDescriptor) public ActionContext([NotNull] RouteContext routeContext, [NotNull] ActionDescriptor actionDescriptor)
@ -39,10 +38,5 @@ namespace Microsoft.AspNet.Mvc
public ModelStateDictionary ModelState { get; private set; } public ModelStateDictionary ModelState { get; private set; }
public ActionDescriptor ActionDescriptor { get; private set; } public ActionDescriptor ActionDescriptor { get; private set; }
/// <summary>
/// The controller is available only after the controller factory runs.
/// </summary>
public object Controller { get; set; }
} }
} }

View File

@ -50,21 +50,16 @@ namespace Microsoft.AspNet.Mvc
} }
} }
public async override Task InvokeAsync() protected override object CreateInstance()
{ {
// The binding context is used in activation // The binding context is used in activation
Debug.Assert(ActionBindingContext != null); Debug.Assert(ActionBindingContext != null);
var controller = _controllerFactory.CreateController(ActionContext); return _controllerFactory.CreateController(ActionContext);
}
try protected override void ReleaseInstance(object instance)
{ {
ActionContext.Controller = controller; _controllerFactory.ReleaseController(instance);
await base.InvokeAsync();
}
finally
{
_controllerFactory.ReleaseController(ActionContext.Controller);
}
} }
protected override async Task<IActionResult> InvokeActionAsync(ActionExecutingContext actionExecutingContext) protected override async Task<IActionResult> InvokeActionAsync(ActionExecutingContext actionExecutingContext)
@ -72,7 +67,7 @@ namespace Microsoft.AspNet.Mvc
var actionMethodInfo = _descriptor.MethodInfo; var actionMethodInfo = _descriptor.MethodInfo;
var actionReturnValue = await ControllerActionExecutor.ExecuteAsync( var actionReturnValue = await ControllerActionExecutor.ExecuteAsync(
actionMethodInfo, actionMethodInfo,
ActionContext.Controller, actionExecutingContext.Controller,
actionExecutingContext.ActionArguments); actionExecutingContext.ActionArguments);
var actionResult = CreateActionResult( var actionResult = CreateActionResult(

View File

@ -37,7 +37,6 @@ namespace Microsoft.AspNet.Mvc
_serviceProvider, _serviceProvider,
actionDescriptor.ControllerTypeInfo.AsType()); actionDescriptor.ControllerTypeInfo.AsType());
actionContext.Controller = controller;
_controllerActivator.Activate(controller, actionContext); _controllerActivator.Activate(controller, actionContext);
return controller; return controller;

View File

@ -55,8 +55,6 @@ namespace Microsoft.AspNet.Mvc
_modelValidatorProviderProvider = modelValidatorProviderProvider; _modelValidatorProviderProvider = modelValidatorProviderProvider;
_valueProviderFactoryProvider = valueProviderFactoryProvider; _valueProviderFactoryProvider = valueProviderFactoryProvider;
_actionBindingContextAccessor = actionBindingContextAccessor; _actionBindingContextAccessor = actionBindingContextAccessor;
ActionBindingContext = new ActionBindingContext();
} }
protected ActionContext ActionContext { get; private set; } protected ActionContext ActionContext { get; private set; }
@ -73,6 +71,21 @@ namespace Microsoft.AspNet.Mvc
} }
} }
protected object Instance { get; private set; }
/// <summary>
/// Called to create an instance of an object which will act as the reciever of the action invocation.
/// </summary>
/// <returns>The constructed instance or <c>null</c>.</returns>
protected abstract object CreateInstance();
/// <summary>
/// Called to create an instance of an object which will act as the reciever of the action invocation.
/// </summary>
/// <param name="instance">The instance to release.</param>
/// <remarks>This method will not be called if <see cref="CreateInstance"/> returns <c>null</c>.</remarks>
protected abstract void ReleaseInstance(object instance);
protected abstract Task<IActionResult> InvokeActionAsync(ActionExecutingContext actionExecutingContext); protected abstract Task<IActionResult> InvokeActionAsync(ActionExecutingContext actionExecutingContext);
protected abstract Task<IDictionary<string, object>> GetActionArgumentsAsync( protected abstract Task<IDictionary<string, object>> GetActionArgumentsAsync(
@ -95,7 +108,20 @@ namespace Microsoft.AspNet.Mvc
return; return;
} }
await InvokeAllResourceFiltersAsync(); try
{
await InvokeAllResourceFiltersAsync();
}
finally
{
// Release the instance after all filters have run. We don't need to surround
// Authorizations filters because the instance will be created much later than
// that.
if (Instance != null)
{
ReleaseInstance(Instance);
}
}
// We've reached the end of resource filters. If there's an unhandled exception on the context then // We've reached the end of resource filters. If there's an unhandled exception on the context then
// it should be thrown and middleware has a chance to handle it. // it should be thrown and middleware has a chance to handle it.
@ -207,7 +233,7 @@ namespace Microsoft.AspNet.Mvc
if (item.FilterAsync != null) if (item.FilterAsync != null)
{ {
await item.FilterAsync.OnResourceExecutionAsync( await item.FilterAsync.OnResourceExecutionAsync(
_resourceExecutingContext, _resourceExecutingContext,
InvokeResourceFilterAsync); InvokeResourceFilterAsync);
if (_resourceExecutedContext == null) if (_resourceExecutedContext == null)
@ -384,23 +410,30 @@ namespace Microsoft.AspNet.Mvc
Debug.Assert(_resourceExecutingContext != null); Debug.Assert(_resourceExecutingContext != null);
Debug.Assert(ActionBindingContext != null); ActionBindingContext = new ActionBindingContext();
ActionBindingContext.InputFormatters = _resourceExecutingContext.InputFormatters; ActionBindingContext.InputFormatters = _resourceExecutingContext.InputFormatters;
ActionBindingContext.ModelBinder = new CompositeModelBinder(_resourceExecutingContext.ModelBinders); ActionBindingContext.ModelBinder = new CompositeModelBinder(_resourceExecutingContext.ModelBinders);
ActionBindingContext.ValidatorProvider = new CompositeModelValidatorProvider( ActionBindingContext.ValidatorProvider = new CompositeModelValidatorProvider(
_resourceExecutingContext.ValidatorProviders); _resourceExecutingContext.ValidatorProviders);
var valueProviderFactoryContext = new ValueProviderFactoryContext( var valueProviderFactoryContext = new ValueProviderFactoryContext(
ActionContext.HttpContext, ActionContext.HttpContext,
ActionContext.RouteData.Values); ActionContext.RouteData.Values);
ActionBindingContext.ValueProvider = CompositeValueProvider.Create( ActionBindingContext.ValueProvider = CompositeValueProvider.Create(
_resourceExecutingContext.ValueProviderFactories, _resourceExecutingContext.ValueProviderFactories,
valueProviderFactoryContext); valueProviderFactoryContext);
Instance = CreateInstance();
var arguments = await GetActionArgumentsAsync(ActionContext, ActionBindingContext); var arguments = await GetActionArgumentsAsync(ActionContext, ActionBindingContext);
_actionExecutingContext = new ActionExecutingContext(ActionContext, _filters, arguments); _actionExecutingContext = new ActionExecutingContext(
ActionContext,
_filters,
arguments,
Instance);
await InvokeActionFilterAsync(); await InvokeActionFilterAsync();
} }
@ -429,7 +462,10 @@ namespace Microsoft.AspNet.Mvc
if (_actionExecutedContext == null) if (_actionExecutedContext == null)
{ {
// If we get here then the filter didn't call 'next' indicating a short circuit // If we get here then the filter didn't call 'next' indicating a short circuit
_actionExecutedContext = new ActionExecutedContext(_actionExecutingContext, _filters) _actionExecutedContext = new ActionExecutedContext(
_actionExecutingContext,
_filters,
Instance)
{ {
Canceled = true, Canceled = true,
Result = _actionExecutingContext.Result, Result = _actionExecutingContext.Result,
@ -443,7 +479,10 @@ namespace Microsoft.AspNet.Mvc
if (_actionExecutingContext.Result != null) if (_actionExecutingContext.Result != null)
{ {
// Short-circuited by setting a result. // Short-circuited by setting a result.
_actionExecutedContext = new ActionExecutedContext(_actionExecutingContext, _filters) _actionExecutedContext = new ActionExecutedContext(
_actionExecutingContext,
_filters,
Instance)
{ {
Canceled = true, Canceled = true,
Result = _actionExecutingContext.Result, Result = _actionExecutingContext.Result,
@ -457,7 +496,10 @@ namespace Microsoft.AspNet.Mvc
else else
{ {
// All action filters have run, execute the action method. // All action filters have run, execute the action method.
_actionExecutedContext = new ActionExecutedContext(_actionExecutingContext, _filters) _actionExecutedContext = new ActionExecutedContext(
_actionExecutingContext,
_filters,
Instance)
{ {
Result = await InvokeActionAsync(_actionExecutingContext), Result = await InvokeActionAsync(_actionExecutingContext),
}; };
@ -466,7 +508,10 @@ namespace Microsoft.AspNet.Mvc
catch (Exception exception) catch (Exception exception)
{ {
// Exceptions thrown by the action method OR filters bubble back up through ActionExcecutedContext. // Exceptions thrown by the action method OR filters bubble back up through ActionExcecutedContext.
_actionExecutedContext = new ActionExecutedContext(_actionExecutingContext, _filters) _actionExecutedContext = new ActionExecutedContext(
_actionExecutingContext,
_filters,
Instance)
{ {
ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception) ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception)
}; };
@ -478,7 +523,7 @@ namespace Microsoft.AspNet.Mvc
{ {
_cursor.SetStage(FilterStage.ResultFilters); _cursor.SetStage(FilterStage.ResultFilters);
_resultExecutingContext = new ResultExecutingContext(ActionContext, _filters, result); _resultExecutingContext = new ResultExecutingContext(ActionContext, _filters, result, Instance);
await InvokeResultFilterAsync(); await InvokeResultFilterAsync();
Debug.Assert(_resultExecutingContext != null); Debug.Assert(_resultExecutingContext != null);
@ -525,7 +570,8 @@ namespace Microsoft.AspNet.Mvc
_resultExecutedContext = new ResultExecutedContext( _resultExecutedContext = new ResultExecutedContext(
_resultExecutingContext, _resultExecutingContext,
_filters, _filters,
_resultExecutingContext.Result) _resultExecutingContext.Result,
Instance)
{ {
Canceled = true, Canceled = true,
}; };
@ -536,7 +582,8 @@ namespace Microsoft.AspNet.Mvc
_resultExecutedContext = new ResultExecutedContext( _resultExecutedContext = new ResultExecutedContext(
_resultExecutingContext, _resultExecutingContext,
_filters, _filters,
_resultExecutingContext.Result) _resultExecutingContext.Result,
Instance)
{ {
Canceled = true, Canceled = true,
}; };
@ -552,7 +599,8 @@ namespace Microsoft.AspNet.Mvc
_resultExecutedContext = new ResultExecutedContext( _resultExecutedContext = new ResultExecutedContext(
_resultExecutingContext, _resultExecutingContext,
_filters, _filters,
_resultExecutingContext.Result) _resultExecutingContext.Result,
Instance)
{ {
Canceled = true, Canceled = true,
}; };
@ -570,7 +618,8 @@ namespace Microsoft.AspNet.Mvc
_resultExecutedContext = new ResultExecutedContext( _resultExecutedContext = new ResultExecutedContext(
_resultExecutingContext, _resultExecutingContext,
_filters, _filters,
_resultExecutingContext.Result); _resultExecutingContext.Result,
Instance);
} }
} }
catch (Exception exception) catch (Exception exception)
@ -578,7 +627,8 @@ namespace Microsoft.AspNet.Mvc
_resultExecutedContext = new ResultExecutedContext( _resultExecutedContext = new ResultExecutedContext(
_resultExecutingContext, _resultExecutingContext,
_filters, _filters,
_resultExecutingContext.Result) _resultExecutingContext.Result,
Instance)
{ {
ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception) ExceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception)
}; };

View File

@ -14,13 +14,17 @@ namespace Microsoft.AspNet.Mvc
public ActionExecutedContext( public ActionExecutedContext(
[NotNull] ActionContext actionContext, [NotNull] ActionContext actionContext,
[NotNull] IList<IFilter> filters) [NotNull] IList<IFilter> filters,
object controller)
: base(actionContext, filters) : base(actionContext, filters)
{ {
Controller = controller;
} }
public virtual bool Canceled { get; set; } public virtual bool Canceled { get; set; }
public virtual object Controller { get; }
public virtual Exception Exception public virtual Exception Exception
{ {
get get

View File

@ -10,14 +10,18 @@ namespace Microsoft.AspNet.Mvc
public ActionExecutingContext( public ActionExecutingContext(
[NotNull] ActionContext actionContext, [NotNull] ActionContext actionContext,
[NotNull] IList<IFilter> filters, [NotNull] IList<IFilter> filters,
[NotNull] IDictionary<string, object> actionArguments) [NotNull] IDictionary<string, object> actionArguments,
object controller)
: base(actionContext, filters) : base(actionContext, filters)
{ {
ActionArguments = actionArguments; ActionArguments = actionArguments;
Controller = controller;
} }
public virtual IActionResult Result { get; set; } public virtual IActionResult Result { get; set; }
public virtual IDictionary<string, object> ActionArguments { get; private set; } public virtual IDictionary<string, object> ActionArguments { get; }
public virtual object Controller { get; }
} }
} }

View File

@ -15,14 +15,18 @@ namespace Microsoft.AspNet.Mvc
public ResultExecutedContext( public ResultExecutedContext(
[NotNull] ActionContext actionContext, [NotNull] ActionContext actionContext,
[NotNull] IList<IFilter> filters, [NotNull] IList<IFilter> filters,
[NotNull] IActionResult result) [NotNull] IActionResult result,
object controller)
: base(actionContext, filters) : base(actionContext, filters)
{ {
Result = result; Result = result;
Controller = controller;
} }
public virtual bool Canceled { get; set; } public virtual bool Canceled { get; set; }
public virtual object Controller { get; }
public virtual Exception Exception public virtual Exception Exception
{ {
get get

View File

@ -10,12 +10,16 @@ namespace Microsoft.AspNet.Mvc
public ResultExecutingContext( public ResultExecutingContext(
[NotNull] ActionContext actionContext, [NotNull] ActionContext actionContext,
[NotNull] IList<IFilter> filters, [NotNull] IList<IFilter> filters,
[NotNull] IActionResult result) [NotNull] IActionResult result,
object controller)
: base(actionContext, filters) : base(actionContext, filters)
{ {
Result = result; Result = result;
Controller = controller;
} }
public virtual object Controller { get; }
public virtual IActionResult Result { get; set; } public virtual IActionResult Result { get; set; }
public virtual bool Cancel { get; set; } public virtual bool Cancel { get; set; }

View File

@ -296,6 +296,7 @@ namespace Microsoft.AspNet.Mvc
// Assert // Assert
filter1.Verify(f => f.OnAuthorization(It.IsAny<AuthorizationContext>()), Times.Once()); filter1.Verify(f => f.OnAuthorization(It.IsAny<AuthorizationContext>()), Times.Once());
Assert.False(invoker.ControllerFactory.CreateCalled);
} }
[Fact] [Fact]
@ -325,6 +326,8 @@ namespace Microsoft.AspNet.Mvc
filter1.Verify( filter1.Verify(
f => f.OnAuthorizationAsync(It.IsAny<AuthorizationContext>()), f => f.OnAuthorizationAsync(It.IsAny<AuthorizationContext>()),
Times.Once()); Times.Once());
Assert.False(invoker.ControllerFactory.CreateCalled);
} }
[Fact] [Fact]
@ -1735,6 +1738,7 @@ namespace Microsoft.AspNet.Mvc
// Assert // Assert
Assert.Same(expected.Object, context.Result); Assert.Same(expected.Object, context.Result);
Assert.True(context.Canceled); Assert.True(context.Canceled);
Assert.False(invoker.ControllerFactory.CreateCalled);
} }
[Fact] [Fact]
@ -1786,6 +1790,7 @@ namespace Microsoft.AspNet.Mvc
// Assert // Assert
Assert.Same(expected.Object, context.Result); Assert.Same(expected.Object, context.Result);
Assert.True(context.Canceled); Assert.True(context.Canceled);
Assert.False(invoker.ControllerFactory.CreateCalled);
} }
[Fact] [Fact]
@ -1847,6 +1852,8 @@ namespace Microsoft.AspNet.Mvc
resourceFilter.Verify( resourceFilter.Verify(
f => f.OnResourceExecutionAsync(It.IsAny<ResourceExecutingContext>(), It.IsAny<ResourceExecutionDelegate>()), f => f.OnResourceExecutionAsync(It.IsAny<ResourceExecutingContext>(), It.IsAny<ResourceExecutionDelegate>()),
Times.Never()); Times.Never());
Assert.False(invoker.ControllerFactory.CreateCalled);
} }
[Fact] [Fact]
@ -1969,10 +1976,6 @@ namespace Microsoft.AspNet.Mvc
routeData: new RouteData(), routeData: new RouteData(),
actionDescriptor: actionDescriptor); actionDescriptor: actionDescriptor);
var controllerFactory = new Mock<IControllerFactory>();
controllerFactory.Setup(c => c.CreateController(It.IsAny<ActionContext>())).Returns(this);
controllerFactory.Setup(m => m.ReleaseController(this)).Verifiable();
var filterProvider = new Mock<INestedProviderManager<FilterProviderContext>>(MockBehavior.Strict); var filterProvider = new Mock<INestedProviderManager<FilterProviderContext>>(MockBehavior.Strict);
filterProvider filterProvider
.Setup(fp => fp.Invoke(It.IsAny<FilterProviderContext>())) .Setup(fp => fp.Invoke(It.IsAny<FilterProviderContext>()))
@ -1985,7 +1988,7 @@ namespace Microsoft.AspNet.Mvc
var invoker = new TestControllerActionInvoker( var invoker = new TestControllerActionInvoker(
actionContext, actionContext,
filterProvider.Object, filterProvider.Object,
controllerFactory, new MockControllerFactory(this),
actionDescriptor, actionDescriptor,
inputFormattersProvider.Object, inputFormattersProvider.Object,
Mock.Of<IControllerActionArgumentBinder>(), Mock.Of<IControllerActionArgumentBinder>(),
@ -1997,8 +2000,6 @@ namespace Microsoft.AspNet.Mvc
return invoker; return invoker;
} }
[Fact] [Fact]
public async Task Invoke_UsesDefaultValuesIfNotBound() public async Task Invoke_UsesDefaultValuesIfNotBound()
{ {
@ -2097,14 +2098,47 @@ namespace Microsoft.AspNet.Mvc
} }
} }
public class TestControllerActionInvoker : ControllerActionInvoker private class MockControllerFactory : IControllerFactory
{ {
private Mock<IControllerFactory> _factoryMock; private object _controller;
public MockControllerFactory(object controller)
{
_controller = controller;
}
public bool CreateCalled { get; private set; }
public bool ReleaseCalled { get; private set; }
public object CreateController(ActionContext actionContext)
{
CreateCalled = true;
return _controller;
}
public void ReleaseController(object controller)
{
Assert.NotNull(controller);
Assert.Same(_controller, controller);
ReleaseCalled = true;
}
public void Verify()
{
if (CreateCalled && !ReleaseCalled)
{
Assert.False(true, "ReleaseController should have been called.");
}
}
}
private class TestControllerActionInvoker : ControllerActionInvoker
{
public TestControllerActionInvoker( public TestControllerActionInvoker(
ActionContext actionContext, ActionContext actionContext,
INestedProviderManager<FilterProviderContext> filterProvider, INestedProviderManager<FilterProviderContext> filterProvider,
Mock<IControllerFactory> controllerFactoryMock, MockControllerFactory controllerFactory,
ControllerActionDescriptor descriptor, ControllerActionDescriptor descriptor,
IInputFormattersProvider inputFormattersProvider, IInputFormattersProvider inputFormattersProvider,
IControllerActionArgumentBinder controllerActionArgumentBinder, IControllerActionArgumentBinder controllerActionArgumentBinder,
@ -2115,7 +2149,7 @@ namespace Microsoft.AspNet.Mvc
: base( : base(
actionContext, actionContext,
filterProvider, filterProvider,
controllerFactoryMock.Object, controllerFactory,
descriptor, descriptor,
inputFormattersProvider, inputFormattersProvider,
controllerActionArgumentBinder, controllerActionArgumentBinder,
@ -2124,14 +2158,17 @@ namespace Microsoft.AspNet.Mvc
valueProviderFactoryProvider, valueProviderFactoryProvider,
actionBindingContext) actionBindingContext)
{ {
_factoryMock = controllerFactoryMock; ControllerFactory = controllerFactory;
} }
public MockControllerFactory ControllerFactory { get; }
public async override Task InvokeAsync() public async override Task InvokeAsync()
{ {
await base.InvokeAsync(); await base.InvokeAsync();
_factoryMock.Verify(); // Make sure that the controller was disposed in every test that creates ones.
ControllerFactory.Verify();
} }
} }
} }

View File

@ -29,10 +29,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
.Returns(services); .Returns(services);
var routeContext = new RouteContext(httpContext.Object); var routeContext = new RouteContext(httpContext.Object);
var controller = new TestController(); var controller = new TestController();
var context = new ActionContext(routeContext, new ActionDescriptor()) var context = new ActionContext(routeContext, new ActionDescriptor());
{
Controller = controller
};
var activator = new DefaultControllerActivator(); var activator = new DefaultControllerActivator();
// Act // Act
@ -55,10 +52,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
.Returns(services); .Returns(services);
var routeContext = new RouteContext(httpContext.Object); var routeContext = new RouteContext(httpContext.Object);
var controller = new TestController(); var controller = new TestController();
var context = new ActionContext(routeContext, new ActionDescriptor()) var context = new ActionContext(routeContext, new ActionDescriptor());
{
Controller = controller
};
var activator = new DefaultControllerActivator(); var activator = new DefaultControllerActivator();
// Act // Act
@ -83,10 +77,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
var routeContext = new RouteContext(httpContext.Object); var routeContext = new RouteContext(httpContext.Object);
var controller = new TestController(); var controller = new TestController();
var context = new ActionContext(routeContext, new ActionDescriptor()) var context = new ActionContext(routeContext, new ActionDescriptor());
{
Controller = controller
};
var activator = new DefaultControllerActivator(); var activator = new DefaultControllerActivator();
@ -109,10 +100,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
.Returns(services); .Returns(services);
var routeContext = new RouteContext(httpContext.Object); var routeContext = new RouteContext(httpContext.Object);
var controller = new TestController(); var controller = new TestController();
var context = new ActionContext(routeContext, new ActionDescriptor()) var context = new ActionContext(routeContext, new ActionDescriptor());
{
Controller = controller
};
var activator = new DefaultControllerActivator(); var activator = new DefaultControllerActivator();
// Act // Act
@ -135,10 +123,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
.Returns(services); .Returns(services);
var routeContext = new RouteContext(httpContext.Object); var routeContext = new RouteContext(httpContext.Object);
var controller = new TestController(); var controller = new TestController();
var context = new ActionContext(routeContext, new ActionDescriptor()) var context = new ActionContext(routeContext, new ActionDescriptor());
{
Controller = controller
};
var activator = new DefaultControllerActivator(); var activator = new DefaultControllerActivator();
// Act // Act

View File

@ -227,12 +227,13 @@ namespace Microsoft.AspNet.Mvc.Test
return new ActionExecutingContext( return new ActionExecutingContext(
CreateActionContext(), CreateActionContext(),
new IFilter[] { filter, }, new IFilter[] { filter, },
new Dictionary<string, object>()); new Dictionary<string, object>(),
controller: new object());
} }
private static ActionExecutedContext CreateActionExecutedContext(ActionExecutingContext context) private static ActionExecutedContext CreateActionExecutedContext(ActionExecutingContext context)
{ {
return new ActionExecutedContext(context, context.Filters) return new ActionExecutedContext(context, context.Filters, context.Controller)
{ {
Result = context.Result, Result = context.Result,
}; };
@ -243,12 +244,13 @@ namespace Microsoft.AspNet.Mvc.Test
return new ResultExecutingContext( return new ResultExecutingContext(
CreateActionContext(), CreateActionContext(),
new IFilter[] { filter, }, new IFilter[] { filter, },
new NoOpResult()); new NoOpResult(),
controller: new object());
} }
private static ResultExecutedContext CreateResultExecutedContext(ResultExecutingContext context) private static ResultExecutedContext CreateResultExecutedContext(ResultExecutingContext context)
{ {
return new ResultExecutedContext(context, context.Filters, context.Result); return new ResultExecutedContext(context, context.Filters, context.Result, context.Controller);
} }
private static ActionContext CreateActionContext() private static ActionContext CreateActionContext()

View File

@ -62,7 +62,7 @@ namespace Microsoft.AspNet.Mvc.Test
private static ResultExecutedContext CreateResultExecutedContext(ResultExecutingContext context) private static ResultExecutedContext CreateResultExecutedContext(ResultExecutingContext context)
{ {
return new ResultExecutedContext(context, context.Filters, context.Result); return new ResultExecutedContext(context, context.Filters, context.Result, context.Controller);
} }
private static ResultExecutingContext CreateResultExecutingContext(IFilter filter) private static ResultExecutingContext CreateResultExecutingContext(IFilter filter)
@ -70,7 +70,8 @@ namespace Microsoft.AspNet.Mvc.Test
return new ResultExecutingContext( return new ResultExecutingContext(
CreateActionContext(), CreateActionContext(),
new IFilter[] { filter, }, new IFilter[] { filter, },
new ObjectResult("Some Value")); new ObjectResult("Some Value"),
controller: new object());
} }
private static ActionContext CreateActionContext() private static ActionContext CreateActionContext()

View File

@ -190,12 +190,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
}) })
.Returns(Task.FromResult(result: false)); .Returns(Task.FromResult(result: false));
var actionContext = new ActionContext( var actionContext = new ActionContext(new RouteContext(Mock.Of<HttpContext>()), actionDescriptor);
new RouteContext(Mock.Of<HttpContext>()),
actionDescriptor)
{
Controller = Mock.Of<object>(),
};
var actionBindingContext = new ActionBindingContext() var actionBindingContext = new ActionBindingContext()
{ {
@ -243,12 +238,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
}) })
.Returns(Task.FromResult(result: true)); .Returns(Task.FromResult(result: true));
var actionContext = new ActionContext( var actionContext = new ActionContext(new RouteContext(Mock.Of<HttpContext>()), actionDescriptor);
new RouteContext(Mock.Of<HttpContext>()),
actionDescriptor)
{
Controller = Mock.Of<object>(),
};
var actionBindingContext = new ActionBindingContext() var actionBindingContext = new ActionBindingContext()
{ {
@ -303,12 +293,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
}) })
.Returns(Task.FromResult(result: true)); .Returns(Task.FromResult(result: true));
var actionContext = new ActionContext( var actionContext = new ActionContext(new RouteContext(Mock.Of<HttpContext>()), actionDescriptor);
new RouteContext(Mock.Of<HttpContext>()),
actionDescriptor)
{
Controller = Mock.Of<object>(),
};
var actionBindingContext = new ActionBindingContext() var actionBindingContext = new ActionBindingContext()
{ {

View File

@ -236,7 +236,8 @@ namespace Microsoft.AspNet.Mvc
return new ActionExecutingContext( return new ActionExecutingContext(
new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()), new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()),
filters ?? new List<IFilter>(), filters ?? new List<IFilter>(),
new Dictionary<string, object>()); new Dictionary<string, object>(),
new object());
} }
} }
} }

View File

@ -34,12 +34,17 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
{ {
// Arrange // Arrange
var filter = new HttpResponseExceptionActionFilter(); var filter = new HttpResponseExceptionActionFilter();
var context = new ActionExecutingContext(new ActionContext(
new DefaultHttpContext(), var actionContext = new ActionContext(
new RouteData(), new DefaultHttpContext(),
actionDescriptor: Mock.Of<ActionDescriptor>()), new RouteData(),
filters: Mock.Of<IList<IFilter>>(), Mock.Of<ActionDescriptor>());
actionArguments: new Dictionary<string, object>());
var context = new ActionExecutingContext(
actionContext,
filters: new List<IFilter>(),
actionArguments: new Dictionary<string, object>(),
controller: new object());
// Act // Act
filter.OnActionExecuting(context); filter.OnActionExecuting(context);
@ -56,12 +61,16 @@ namespace Microsoft.AspNet.Mvc.WebApiCompatShim
var httpContext = new DefaultHttpContext(); var httpContext = new DefaultHttpContext();
httpContext.Request.Method = "GET"; httpContext.Request.Method = "GET";
var actionContext = new ActionContext(
httpContext,
new RouteData(),
Mock.Of<ActionDescriptor>());
var context = new ActionExecutedContext( var context = new ActionExecutedContext(
new ActionContext( actionContext,
httpContext, filters: new List<IFilter>(),
new RouteData(), controller: new object());
actionDescriptor: Mock.Of<ActionDescriptor>()),
filters: null);
context.Exception = new HttpResponseException(HttpStatusCode.BadRequest); context.Exception = new HttpResponseException(HttpStatusCode.BadRequest);
// Act // Act