[Perf] Remove the validations in ControllerActivator and ViewComponentActivator which are redundant. These

validations are already done when selecting a controller and view component
Fixes #4367
This commit is contained in:
mnltejaswini 2016-04-07 11:18:37 -07:00
parent 1d4363305c
commit f4e35f5ba0
6 changed files with 29 additions and 110 deletions

View File

@ -46,16 +46,12 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
} }
var controllerTypeInfo = controllerContext.ActionDescriptor.ControllerTypeInfo; var controllerTypeInfo = controllerContext.ActionDescriptor.ControllerTypeInfo;
if (controllerTypeInfo.IsValueType ||
controllerTypeInfo.IsInterface ||
controllerTypeInfo.IsAbstract ||
(controllerTypeInfo.IsGenericType && controllerTypeInfo.IsGenericTypeDefinition))
{
var message = Resources.FormatValueInterfaceAbstractOrOpenGenericTypesCannotBeActivated(
controllerTypeInfo.FullName,
GetType().FullName);
throw new InvalidOperationException(message); if (controllerTypeInfo == null)
{
throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull(
nameof(controllerContext.ActionDescriptor.ControllerTypeInfo),
nameof(ControllerContext.ActionDescriptor)));
} }
var serviceProvider = controllerContext.HttpContext.RequestServices; var serviceProvider = controllerContext.HttpContext.RequestServices;

View File

@ -45,17 +45,12 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents
} }
var componentType = context.ViewComponentDescriptor.TypeInfo; var componentType = context.ViewComponentDescriptor.TypeInfo;
if (componentType.IsValueType || if (componentType == null)
componentType.IsInterface ||
componentType.IsAbstract ||
(componentType.IsGenericType && componentType.IsGenericTypeDefinition))
{ {
var message = Resources.FormatValueInterfaceAbstractOrOpenGenericTypesCannotBeActivated( throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull(
componentType.FullName, nameof(context.ViewComponentDescriptor.TypeInfo),
GetType().FullName); nameof(context.ViewComponentDescriptor)));
throw new InvalidOperationException(message);
} }
var viewComponent = _typeActivatorCache.CreateInstance<object>( var viewComponent = _typeActivatorCache.CreateInstance<object>(

View File

@ -121,6 +121,21 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
// Assert // Assert
Assert.Empty(feature.Controllers); Assert.Empty(feature.Controllers);
} }
[Fact]
public void ValueTypeClass_IsNotController()
{
// Arrange
var controllerType = typeof(int).GetTypeInfo();
var manager = GetApplicationPartManager(controllerType);
var feature = new ControllerFeature();
// Act
manager.PopulateFeature(feature);
// Assert
Assert.Empty(feature.Controllers);
}
[Fact] [Fact]
public void AbstractClass_IsNotController() public void AbstractClass_IsNotController()

View File

@ -58,38 +58,7 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
// Assert // Assert
Assert.Equal(true, controller.Disposed); Assert.Equal(true, controller.Disposed);
} }
[Theory]
[InlineData(typeof(int))]
[InlineData(typeof(OpenGenericType<>))]
[InlineData(typeof(AbstractType))]
[InlineData(typeof(InterfaceType))]
public void CreateController_ThrowsIfControllerCannotBeActivated(Type type)
{
// Arrange
var actionDescriptor = new ControllerActionDescriptor
{
ControllerTypeInfo = type.GetTypeInfo()
};
var context = new ControllerContext()
{
ActionDescriptor = actionDescriptor,
HttpContext = new DefaultHttpContext()
{
RequestServices = GetServices(),
},
};
var factory = new DefaultControllerActivator(new TypeActivatorCache());
// Act and Assert
var exception = Assert.Throws<InvalidOperationException>(() => factory.Create(context));
Assert.Equal(
$"The type '{type.FullName}' cannot be activated by '{typeof(DefaultControllerActivator).FullName}' " +
"because it is either a value type, an interface, an abstract class or an open generic type.",
exception.Message);
}
[Fact] [Fact]
public void DefaultControllerActivator_ReleasesNonIDisposableController() public void DefaultControllerActivator_ReleasesNonIDisposableController()
{ {
@ -174,18 +143,6 @@ namespace Microsoft.AspNetCore.Mvc.Controllers
{ {
} }
private class OpenGenericType<T> : Controller
{
}
private abstract class AbstractType : Controller
{
}
private interface InterfaceType
{
}
private class MyController : IDisposable private class MyController : IDisposable
{ {
public bool Disposed { get; set; } public bool Disposed { get; set; }

View File

@ -38,41 +38,6 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents
Assert.Same(context, instance.ViewComponentContext); Assert.Same(context, instance.ViewComponentContext);
} }
[Theory]
[InlineData(typeof(int))]
[InlineData(typeof(OpenGenericType<>))]
[InlineData(typeof(AbstractType))]
[InlineData(typeof(InterfaceType))]
public void Create_ThrowsIfControllerCannotBeActivated(Type type)
{
// Arrange
var actionDescriptor = new ViewComponentDescriptor
{
TypeInfo = type.GetTypeInfo()
};
var context = new ViewComponentContext
{
ViewComponentDescriptor = actionDescriptor,
ViewContext = new ViewContext
{
HttpContext = new DefaultHttpContext()
{
RequestServices = Mock.Of<IServiceProvider>()
},
}
};
var activator = new DefaultViewComponentActivator(new TypeActivatorCache());
// Act and Assert
var exception = Assert.Throws<InvalidOperationException>(() => activator.Create(context));
Assert.Equal(
$"The type '{type.FullName}' cannot be activated by '{typeof(DefaultViewComponentActivator).FullName}' " +
"because it is either a value type, an interface, an abstract class or an open generic type.",
exception.Message);
}
[Fact] [Fact]
public void DefaultViewComponentActivator_ActivatesViewComponentContext_IgnoresNonPublic() public void DefaultViewComponentActivator_ActivatesViewComponentContext_IgnoresNonPublic()
{ {
@ -116,18 +81,6 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents
}; };
} }
private class OpenGenericType<T> : Controller
{
}
private abstract class AbstractType : Controller
{
}
private interface InterfaceType
{
}
private class TestViewComponent : ViewComponent private class TestViewComponent : ViewComponent
{ {
public Task ExecuteAsync() public Task ExecuteAsync()

View File

@ -35,6 +35,9 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents
// The Attribute does apply to derived classes. // The Attribute does apply to derived classes.
[InlineData(typeof(WithAttribute), true)] [InlineData(typeof(WithAttribute), true)]
[InlineData(typeof(DerivedWithAttribute), true)] [InlineData(typeof(DerivedWithAttribute), true)]
// Value types cannot be view components
[InlineData(typeof(int), false)]
public void IsComponent(Type type, bool expected) public void IsComponent(Type type, bool expected)
{ {
// Arrange & Act // Arrange & Act