using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace Microsoft.AspNet.Mvc { public class DefaultControllerDescriptorProvider : IControllerDescriptorProvider { private readonly IControllerAssemblyProvider _controllerAssemblyProvider; public IReadOnlyDictionary> Controllers { get; protected set; } public void FinalizeSetup() { Controllers = ScanAppDomain(); } public DefaultControllerDescriptorProvider(IControllerAssemblyProvider controllerAssemblyProvider) { if (controllerAssemblyProvider == null) { throw new ArgumentNullException("controllerAssemblyProvider"); } _controllerAssemblyProvider = controllerAssemblyProvider; } public IEnumerable GetControllers(string controllerName) { if (!controllerName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)) { controllerName += "Controller"; } if (Controllers == null) { throw new InvalidOperationException("Finalizing the setup must happen prior to accessing controllers"); } IEnumerable descriptors = null; if (Controllers.TryGetValue(controllerName, out descriptors)) { return descriptors; } return Enumerable.Empty(); } public Dictionary> ScanAppDomain() { var dictionary = new Dictionary>(StringComparer.Ordinal); foreach (var assembly in _controllerAssemblyProvider.Assemblies) { foreach (var type in assembly.DefinedTypes.Where(IsController).Select(info => info.AsType())) { var descriptor = new ControllerDescriptor(type, assembly); IEnumerable controllerDescriptors; if (!dictionary.TryGetValue(type.Name, out controllerDescriptors)) { controllerDescriptors = new List(); dictionary.Add(descriptor.ControllerName, controllerDescriptors); } ((List)controllerDescriptors).Add(descriptor); } } return dictionary; } public virtual bool IsController(TypeInfo typeInfo) { if (typeInfo == null) { throw new ArgumentNullException("typeInfo"); } bool validController = typeInfo.IsClass && !typeInfo.IsAbstract && !typeInfo.ContainsGenericParameters; validController = validController && typeInfo.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase); return validController; } } }