using System; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using System.Web.Routing; using Umbraco.Core; using Umbraco.Core.Configuration; namespace Umbraco.Web.Mvc { /// /// A custom area for controllers that are plugins /// internal class PluginControllerArea : AreaRegistration { private readonly IEnumerable _surfaceControllers; private readonly string _areaName; /// /// The constructor accepts all types of plugin controllers and will verify that ALL of them have the same areaName assigned to them /// based on their PluginControllerAttribute. If they are not the same an exception will be thrown. /// /// public PluginControllerArea(IEnumerable pluginControllers) { //TODO: When we have other future plugin controllers we need to combine them all into one list here to do our validation. var controllers = pluginControllers.ToArray(); if (controllers.Any(x => x.AreaName.IsNullOrWhiteSpace())) { throw new InvalidOperationException("Cannot create a PluginControllerArea unless all plugin controllers assigned have a PluginControllerAttribute assigned"); } _areaName = controllers.First().AreaName; foreach(var c in controllers) { if (c.AreaName != _areaName) { throw new InvalidOperationException("Cannot create a PluginControllerArea unless all plugin controllers assigned have the same AreaName. The first AreaName found was " + _areaName + " however, the controller of type " + c.GetType().FullName + " has an AreaName of " + c.AreaName); } } //get the surface controllers _surfaceControllers = controllers.Where(x => TypeHelper.IsTypeAssignableFrom(x.ControllerType)); } public override void RegisterArea(AreaRegistrationContext context) { MapRouteSurfaceControllers(context.Routes, _surfaceControllers); } public override string AreaName { get { return _areaName; } } /// /// Registers all surface controller routes /// /// /// /// /// The routes will be: /// /// /Umbraco/[AreaName]/[ControllerName]/[Action]/[Id] /// private void MapRouteSurfaceControllers(RouteCollection routes, IEnumerable surfaceControllers) { foreach (var s in surfaceControllers) { this.RouteControllerPlugin(s.ControllerName, s.ControllerType, routes, "", "Index", UrlParameter.Optional, "surface"); } } } }