using System;
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 ConcurrentDictionary();
// for debugging purposes
internal Guid InstanceId { get; } = Guid.NewGuid();
///
/// Gets the Umbraco context.
///
public virtual IUmbracoContext UmbracoContext
{
get
{
if (!UmbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext))
{
throw new InvalidOperationException("Wasn't able to get an UmbracoContext");
}
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());
protected PluginController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger)
{
UmbracoContextAccessor = umbracoContextAccessor;
DatabaseFactory = databaseFactory;
Services = services;
AppCaches = appCaches;
ProfilingLogger = profilingLogger;
}
///
/// Gets metadata for a controller type.
///
/// The controller type.
/// Metadata for the controller type.
public static PluginControllerMetadata GetMetadata(Type controllerType)
{
return MetadataStorage.GetOrAdd(controllerType, type =>
{
// plugin controller? back-office controller?
var pluginAttribute = controllerType.GetCustomAttribute(false);
var backOfficeAttribute = controllerType.GetCustomAttribute(true);
return new PluginControllerMetadata
{
AreaName = pluginAttribute?.AreaName,
ControllerName = ControllerExtensions.GetControllerName(controllerType),
ControllerNamespace = controllerType.Namespace,
ControllerType = controllerType,
IsBackOffice = backOfficeAttribute != null
};
});
}
}
}