Dispose controllers after they have been utilized by the action invoker
This commit is contained in:
parent
0a62a581de
commit
ebd54bfc06
|
|
@ -30,7 +30,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
var controller = _activator.CreateInstance(_serviceProvider, actionDescriptor.ControllerDescriptor.ControllerTypeInfo.AsType());
|
||||
|
||||
// TODO: How do we feed the controller with context (need DI improvements)
|
||||
InitializeController(controller, actionContext);
|
||||
|
||||
return controller;
|
||||
|
|
@ -38,6 +37,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
public void ReleaseController(object controller)
|
||||
{
|
||||
var disposableController = controller as IDisposable;
|
||||
|
||||
if (disposableController != null)
|
||||
{
|
||||
disposableController.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeController(object controller, ActionContext actionContext)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public interface IControllerFactory
|
||||
{
|
||||
object CreateController(ActionContext actionContext);
|
||||
|
||||
void ReleaseController(object controller);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,8 +48,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
public async Task InvokeActionAsync()
|
||||
{
|
||||
IActionResult actionResult;
|
||||
|
||||
var filterMetaItems = GetAndArrangeFilters();
|
||||
|
||||
var controller = _controllerFactory.CreateController(_actionContext);
|
||||
|
|
@ -61,10 +59,17 @@ namespace Microsoft.AspNet.Mvc
|
|||
"controller"));
|
||||
}
|
||||
|
||||
actionResult = await RunAuthorizationFilters(filterMetaItems) ??
|
||||
await RunActionFiltersAndActions(filterMetaItems, controller);
|
||||
try
|
||||
{
|
||||
var actionResult = await RunAuthorizationFilters(filterMetaItems) ??
|
||||
await RunActionFiltersAndActions(filterMetaItems, controller);
|
||||
|
||||
await RunActionResultFilters(actionResult, filterMetaItems);
|
||||
await RunActionResultFilters(actionResult, filterMetaItems);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_controllerFactory.ReleaseController(controller);
|
||||
}
|
||||
}
|
||||
|
||||
private FilterItem[] GetAndArrangeFilters()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.DependencyInjection;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Core.Test
|
||||
{
|
||||
public class DefaultControllerFactoryTest
|
||||
{
|
||||
[Fact]
|
||||
public void DefaultControllerFactory_DisposesIDisposableController()
|
||||
{
|
||||
// Arrange
|
||||
var factory = new DefaultControllerFactory(
|
||||
new Mock<IServiceProvider>().Object,
|
||||
new Mock<ITypeActivator>().Object);
|
||||
|
||||
var controller = new MyController();
|
||||
|
||||
// Act + Assert
|
||||
Assert.False(controller.Disposed);
|
||||
|
||||
factory.ReleaseController(controller);
|
||||
|
||||
Assert.True(controller.Disposed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DefaultControllerFactory_ReleasesNonIDisposableController()
|
||||
{
|
||||
// Arrange
|
||||
var factory = new DefaultControllerFactory(
|
||||
new Mock<IServiceProvider>().Object,
|
||||
new Mock<ITypeActivator>().Object);
|
||||
|
||||
var controller = new Object();
|
||||
|
||||
// Act + Assert
|
||||
Assert.DoesNotThrow(() => factory.ReleaseController(controller));
|
||||
}
|
||||
|
||||
private class MyController : Controller, IDisposable
|
||||
{
|
||||
public bool Disposed { get; set; }
|
||||
public void Dispose()
|
||||
{
|
||||
Disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue