80 lines
2.5 KiB
C#
80 lines
2.5 KiB
C#
// Copyright (c) .NET Foundation. 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.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
|
|
|
namespace Microsoft.AspNetCore.Mvc.Controllers
|
|
{
|
|
/// <summary>
|
|
/// Discovers controllers from a list of <see cref="ApplicationPart"/> instances.
|
|
/// </summary>
|
|
public class ControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>
|
|
{
|
|
private const string ControllerTypeNameSuffix = "Controller";
|
|
|
|
/// <inheritdoc />
|
|
public void PopulateFeature(
|
|
IEnumerable<ApplicationPart> parts,
|
|
ControllerFeature feature)
|
|
{
|
|
foreach (var part in parts.OfType<IApplicationPartTypeProvider>())
|
|
{
|
|
foreach (var type in part.Types)
|
|
{
|
|
if (IsController(type) && !feature.Controllers.Contains(type))
|
|
{
|
|
feature.Controllers.Add(type);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines if a given <paramref name="typeInfo"/> is a controller.
|
|
/// </summary>
|
|
/// <param name="typeInfo">The <see cref="TypeInfo"/> candidate.</param>
|
|
/// <returns><code>true</code> if the type is a controller; otherwise <code>false</code>.</returns>
|
|
protected virtual bool IsController(TypeInfo typeInfo)
|
|
{
|
|
if (!typeInfo.IsClass)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (typeInfo.IsAbstract)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// We only consider public top-level classes as controllers. IsPublic returns false for nested
|
|
// classes, regardless of visibility modifiers
|
|
if (!typeInfo.IsPublic)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (typeInfo.ContainsGenericParameters)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (typeInfo.IsDefined(typeof(NonControllerAttribute)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!typeInfo.Name.EndsWith(ControllerTypeNameSuffix, StringComparison.OrdinalIgnoreCase) &&
|
|
!typeInfo.IsDefined(typeof(ControllerAttribute)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|