// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
using System.Reflection;
using Microsoft.AspNet.Mvc.Description;
using Microsoft.AspNet.Mvc.Routing;
namespace Microsoft.AspNet.Mvc.ApplicationModels
{
///
/// A default implementation of .
///
public class DefaultControllerModelBuilder : IControllerModelBuilder
{
private readonly IActionModelBuilder _actionModelBuilder;
///
/// Creates a new .
///
/// The used to create actions.
public DefaultControllerModelBuilder(IActionModelBuilder actionModelBuilder)
{
_actionModelBuilder = actionModelBuilder;
}
///
public ControllerModel BuildControllerModel([NotNull] TypeInfo typeInfo)
{
if (!IsController(typeInfo))
{
return null;
}
var controllerModel = CreateControllerModel(typeInfo);
foreach (var methodInfo in typeInfo.AsType().GetMethods())
{
var actionModels = _actionModelBuilder.BuildActionModels(typeInfo, methodInfo);
if (actionModels != null)
{
foreach (var actionModel in actionModels)
{
actionModel.Controller = controllerModel;
controllerModel.Actions.Add(actionModel);
}
}
}
return controllerModel;
}
///
/// Returns true if the is a controller. Otherwise false.
///
/// The .
/// true if the is a controller. Otherwise false.
///
/// Override this method to provide custom logic to determine which types are considered controllers.
///
protected virtual bool IsController([NotNull] TypeInfo typeInfo)
{
if (!typeInfo.IsClass ||
typeInfo.IsAbstract ||
// We only consider public top-level classes as controllers. IsPublic returns false for nested
// classes, regardless of visibility modifiers.
!typeInfo.IsPublic ||
typeInfo.ContainsGenericParameters)
{
return false;
}
if (typeInfo.Name.Equals("Controller", StringComparison.OrdinalIgnoreCase))
{
return false;
}
return typeInfo.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) ||
typeof(Controller).GetTypeInfo().IsAssignableFrom(typeInfo);
}
///
/// Creates an for the given .
///
/// The .
/// A for the given .
protected virtual ControllerModel CreateControllerModel([NotNull] TypeInfo typeInfo)
{
// CoreCLR returns IEnumerable from GetCustomAttributes - the OfType