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());
|
var controller = _activator.CreateInstance(_serviceProvider, actionDescriptor.ControllerDescriptor.ControllerTypeInfo.AsType());
|
||||||
|
|
||||||
// TODO: How do we feed the controller with context (need DI improvements)
|
|
||||||
InitializeController(controller, actionContext);
|
InitializeController(controller, actionContext);
|
||||||
|
|
||||||
return controller;
|
return controller;
|
||||||
|
|
@ -38,6 +37,12 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
public void ReleaseController(object controller)
|
public void ReleaseController(object controller)
|
||||||
{
|
{
|
||||||
|
var disposableController = controller as IDisposable;
|
||||||
|
|
||||||
|
if (disposableController != null)
|
||||||
|
{
|
||||||
|
disposableController.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeController(object controller, ActionContext actionContext)
|
private void InitializeController(object controller, ActionContext actionContext)
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
|
namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc
|
|
||||||
{
|
{
|
||||||
public interface IControllerFactory
|
public interface IControllerFactory
|
||||||
{
|
{
|
||||||
object CreateController(ActionContext actionContext);
|
object CreateController(ActionContext actionContext);
|
||||||
|
|
||||||
void ReleaseController(object controller);
|
void ReleaseController(object controller);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,6 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
public async Task InvokeActionAsync()
|
public async Task InvokeActionAsync()
|
||||||
{
|
{
|
||||||
IActionResult actionResult;
|
|
||||||
|
|
||||||
var filterMetaItems = GetAndArrangeFilters();
|
var filterMetaItems = GetAndArrangeFilters();
|
||||||
|
|
||||||
var controller = _controllerFactory.CreateController(_actionContext);
|
var controller = _controllerFactory.CreateController(_actionContext);
|
||||||
|
|
@ -61,10 +59,17 @@ namespace Microsoft.AspNet.Mvc
|
||||||
"controller"));
|
"controller"));
|
||||||
}
|
}
|
||||||
|
|
||||||
actionResult = await RunAuthorizationFilters(filterMetaItems) ??
|
try
|
||||||
await RunActionFiltersAndActions(filterMetaItems, controller);
|
{
|
||||||
|
var actionResult = await RunAuthorizationFilters(filterMetaItems) ??
|
||||||
|
await RunActionFiltersAndActions(filterMetaItems, controller);
|
||||||
|
|
||||||
await RunActionResultFilters(actionResult, filterMetaItems);
|
await RunActionResultFilters(actionResult, filterMetaItems);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_controllerFactory.ReleaseController(controller);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private FilterItem[] GetAndArrangeFilters()
|
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