using System; using System.Linq; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Umbraco.Cms.Core.Composing; using Umbraco.Cms.Core.DependencyInjection; namespace Umbraco.Cms.Web.UI.Composers { /// /// Adds controllers to the service collection. /// /// /// /// Umbraco 9 out of the box, makes use of which doesn't resolve controller /// instances from the IOC container, instead it resolves the required dependencies of the controller and constructs an instance /// of the controller. /// /// /// Some users may wish to switch to (perhaps to make use of interception/decoration). /// /// /// This composer exists to help us detect ambiguous constructors in the CMS such that we do not cause unnecessary effort downstream. /// /// /// This Composer is not shipped by the Umbraco.Templates package. /// /// public class ControllersAsServicesComposer : IComposer { /// public void Compose(IUmbracoBuilder builder) => builder.Services .AddMvc() .AddControllersAsServicesWithoutChangingActivator(); } internal static class MvcBuilderExtensions { /// /// but without the replacement of /// . /// /// /// We don't need to opt in to to ensure container validation /// passes. /// public static IMvcBuilder AddControllersAsServicesWithoutChangingActivator(this IMvcBuilder builder) { var feature = new ControllerFeature(); builder.PartManager.PopulateFeature(feature); foreach (Type controller in feature.Controllers.Select(c => c.AsType())) { builder.Services.TryAddTransient(controller, controller); } return builder; } } }