using System;
using System.Collections.Concurrent;
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Composing;
using Umbraco.Core.Services;
using Umbraco.Web.Security;
using Umbraco.Web.WebApi;
namespace Umbraco.Web.Mvc
{
///
/// Provides a base class for plugin controllers.
///
public abstract class PluginController : Controller, IDiscoverable
{
private static readonly ConcurrentDictionary MetadataStorage
= new ConcurrentDictionary();
private UmbracoHelper _umbracoHelper;
// for debugging purposes
internal Guid InstanceId { get; } = Guid.NewGuid();
// note
// properties marked as [Inject] below will be property-injected (vs constructor-injected) in
// order to keep the constuctor as light as possible, so that ppl implementing eg a SurfaceController
// don't need to implement complex constructors + need to refactor them each time we change ours.
// this means that these properties have a setter.
// what can go wrong?
///
/// Gets or sets the Umbraco context.
///
public virtual UmbracoContext UmbracoContext { get; }
///
/// Gets or sets the database context.
///
public IUmbracoDatabaseFactory DatabaseFactory { get; }
///
/// Gets or sets the services context.
///
public ServiceContext Services { get; }
///
/// Gets or sets the application cache.
///
public CacheHelper ApplicationCache { get; }
///
/// Gets or sets the logger.
///
public ILogger Logger { get; }
///
/// Gets or sets the profiling logger.
///
public ProfilingLogger ProfilingLogger { get; }
///
/// Gets the membership helper.
///
public MembershipHelper Members => Umbraco.MembershipHelper;
///
/// Gets the Umbraco helper.
///
public UmbracoHelper Umbraco
{
get
{
return _umbracoHelper
?? (_umbracoHelper = new UmbracoHelper(UmbracoContext, Services, ApplicationCache));
}
internal set // tests
{
_umbracoHelper = value;
}
}
///
/// Gets metadata for this instance.
///
internal PluginControllerMetadata Metadata => GetMetadata(GetType());
protected PluginController()
: this(
Current.Container.GetInstance(),
Current.Container.GetInstance(),
Current.Container.GetInstance(),
Current.Container.GetInstance(),
Current.Container.GetInstance(),
Current.Container.GetInstance()
)
{
}
protected PluginController(UmbracoContext umbracoContext, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, CacheHelper applicationCache, ILogger logger, ProfilingLogger profilingLogger)
{
UmbracoContext = umbracoContext;
DatabaseFactory = databaseFactory;
Services = services;
ApplicationCache = applicationCache;
Logger = logger;
ProfilingLogger = profilingLogger;
}
///
/// Gets metadata for a controller type.
///
/// The controller type.
/// Metadata for the controller type.
internal 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
};
});
}
}
}