using System.Collections.Concurrent; using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Composing; using Umbraco.Cms.Core.Logging; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Web; using Umbraco.Cms.Core.Web.Mvc; using Umbraco.Cms.Infrastructure.Persistence; using Umbraco.Cms.Web.Common.Attributes; using Umbraco.Extensions; namespace Umbraco.Cms.Web.Common.Controllers; /// /// Provides a base class for plugin controllers. /// public abstract class PluginController : Controller, IDiscoverable { private static readonly ConcurrentDictionary MetadataStorage = new(); protected PluginController( IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger) { UmbracoContextAccessor = umbracoContextAccessor; DatabaseFactory = databaseFactory; Services = services; AppCaches = appCaches; ProfilingLogger = profilingLogger; } /// /// Gets the Umbraco context. /// public virtual IUmbracoContext UmbracoContext { get { IUmbracoContext umbracoContext = UmbracoContextAccessor.GetRequiredUmbracoContext(); return umbracoContext; } } /// /// Gets the database context accessor. /// public virtual IUmbracoContextAccessor UmbracoContextAccessor { get; } /// /// Gets the database context. /// public IUmbracoDatabaseFactory DatabaseFactory { get; } /// /// Gets or sets the services context. /// public ServiceContext Services { get; } /// /// Gets or sets the application cache. /// public AppCaches AppCaches { get; } /// /// Gets or sets the profiling logger. /// public IProfilingLogger ProfilingLogger { get; } /// /// Gets metadata for this instance. /// internal PluginControllerMetadata Metadata => GetMetadata(GetType()); // for debugging purposes internal Guid InstanceId { get; } = Guid.NewGuid(); /// /// Gets metadata for a controller type. /// /// The controller type. /// Metadata for the controller type. public static PluginControllerMetadata GetMetadata(Type controllerType) => MetadataStorage.GetOrAdd(controllerType, type => { // plugin controller? back-office controller? PluginControllerAttribute? pluginAttribute = controllerType.GetCustomAttribute(false); IsBackOfficeAttribute? backOfficeAttribute = controllerType.GetCustomAttribute(true); return new PluginControllerMetadata { AreaName = pluginAttribute?.AreaName, ControllerName = ControllerExtensions.GetControllerName(controllerType), ControllerNamespace = controllerType.Namespace, ControllerType = controllerType, IsBackOffice = backOfficeAttribute != null, }; }); }