// 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 Microsoft.AspNetCore.Mvc.ApplicationModels; namespace Microsoft.AspNetCore.Mvc.Internal { /// /// Applies conventions to a . /// public static class ApplicationModelConventions { /// /// Applies conventions to a . /// /// The . /// The set of conventions. public static void ApplyConventions( ApplicationModel applicationModel, IEnumerable conventions) { if (applicationModel == null) { throw new ArgumentNullException(nameof(applicationModel)); } if (conventions == null) { throw new ArgumentNullException(nameof(conventions)); } // Conventions are applied from the outside-in to allow for scenarios where an action overrides // a controller, etc. foreach (var convention in conventions) { convention.Apply(applicationModel); } var controllers = applicationModel.Controllers.ToArray(); // First apply the conventions from attributes in decreasing order of scope. foreach (var controller in controllers) { // ToArray is needed here to prevent issues with modifying the attributes collection // while iterating it. var controllerConventions = controller.Attributes .OfType() .ToArray(); foreach (var controllerConvention in controllerConventions) { controllerConvention.Apply(controller); } var actions = controller.Actions.ToArray(); foreach (var action in actions) { // ToArray is needed here to prevent issues with modifying the attributes collection // while iterating it. var actionConventions = action.Attributes .OfType() .ToArray(); foreach (var actionConvention in actionConventions) { actionConvention.Apply(action); } var parameters = action.Parameters.ToArray(); foreach (var parameter in parameters) { // ToArray is needed here to prevent issues with modifying the attributes collection // while iterating it. var parameterConventions = parameter.Attributes .OfType() .ToArray(); foreach (var parameterConvention in parameterConventions) { parameterConvention.Apply(parameter); } var parameterBaseConventions = GetConventions(conventions, parameter.Attributes); foreach (var parameterConvention in parameterBaseConventions) { parameterConvention.Apply(parameter); } } } var properties = controller.ControllerProperties.ToArray(); foreach (var property in properties) { var parameterBaseConventions = GetConventions(conventions, property.Attributes); foreach (var parameterConvention in parameterBaseConventions) { parameterConvention.Apply(property); } } } } private static IEnumerable GetConventions( IEnumerable conventions, IReadOnlyList attributes) { return Enumerable.Concat( conventions.OfType(), attributes.OfType()); } } }