using System;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Dictionary;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PackageActions;
using Umbraco.Core.Packaging;
using Umbraco.Core.Persistence;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
using Umbraco.Core.Sync;
namespace Umbraco.Core.Composing
{
///
/// Provides a static service locator for most singletons.
///
///
/// This class is initialized with the container in UmbracoApplicationBase,
/// right after the container is created in UmbracoApplicationBase.HandleApplicationStart.
/// Obviously, this is a service locator, which some may consider an anti-pattern. And yet,
/// practically, it works.
///
public static class Current
{
private static IFactory _factory;
// TODO: get rid of these oddities
// we don't want Umbraco tests to die because the container has not been properly initialized,
// for some too-important things such as IShortStringHelper or loggers, so if it's not
// registered we setup a default one. We should really refactor our tests so that it does
// not happen.
private static IShortStringHelper _shortStringHelper;
private static ILogger _logger;
private static IProfiler _profiler;
private static IProfilingLogger _profilingLogger;
private static IPublishedValueFallback _publishedValueFallback;
private static Configs _configs;
///
/// Gets or sets the factory.
///
public static IFactory Factory
{
get
{
if (_factory == null) throw new InvalidOperationException("No factory has been set.");
return _factory;
}
set
{
if (_factory != null) throw new InvalidOperationException("A factory has already been set.");
if (_configs != null) throw new InvalidOperationException("Configs are unlocked.");
_factory = value;
}
}
internal static bool HasFactory => _factory != null;
///
/// Resets . Indented for testing only, and not supported in production code.
///
///
/// For UNIT TESTS exclusively.
/// Resets everything that is 'current'.
///
public static void Reset()
{
_factory.DisposeIfDisposable();
_factory = null;
_configs = null;
_shortStringHelper = null;
_logger = null;
_profiler = null;
_profilingLogger = null;
_publishedValueFallback = null;
Resetted?.Invoke(null, EventArgs.Empty);
}
///
/// Unlocks . Intended for testing only, and not supported in production code.
///
///
/// For UNIT TESTS exclusively.
/// Unlocks so that it is possible to add configurations
/// directly to without having to wire composition.
///
public static void UnlockConfigs()
{
if (_factory != null)
throw new InvalidOperationException("Cannot unlock configs when a factory has been set.");
_configs = new Configs();
}
internal static event EventHandler Resetted;
#region Getters
public static UmbracoMapper Mapper
=> _factory.GetInstance();
public static IShortStringHelper ShortStringHelper
=> _shortStringHelper ?? (_shortStringHelper = _factory?.TryGetInstance()
?? new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(Configs.Settings())));
public static ILogger Logger
=> _logger ?? (_logger = _factory?.TryGetInstance()
?? new DebugDiagnosticsLogger());
public static IProfiler Profiler
=> _profiler ?? (_profiler = _factory?.TryGetInstance()
?? new LogProfiler(Logger));
public static IProfilingLogger ProfilingLogger
=> _profilingLogger ?? (_profilingLogger = _factory?.TryGetInstance())
?? new ProfilingLogger(Logger, Profiler);
public static IRuntimeState RuntimeState
=> Factory.GetInstance();
public static TypeLoader TypeLoader
=> Factory.GetInstance();
public static Configs Configs
{
get
{
if (_configs != null) return _configs;
if (_factory == null) throw new InvalidOperationException("Can not get Current.Config during composition. Use composition.Config.");
return _factory.GetInstance();
}
}
public static IFileSystems FileSystems
=> Factory.GetInstance();
public static IMediaFileSystem MediaFileSystem
=> Factory.GetInstance();
public static UrlSegmentProviderCollection UrlSegmentProviders
=> Factory.GetInstance();
public static CacheRefresherCollection CacheRefreshers
=> Factory.GetInstance();
public static DataEditorCollection DataEditors
=> Factory.GetInstance();
public static PropertyEditorCollection PropertyEditors
=> Factory.GetInstance();
public static ParameterEditorCollection ParameterEditors
=> Factory.GetInstance();
internal static ManifestValueValidatorCollection ManifestValidators
=> Factory.GetInstance();
internal static PackageActionCollection PackageActions
=> Factory.GetInstance();
internal static IPackageActionRunner PackageActionRunner
=> Factory.GetInstance();
internal static PropertyValueConverterCollection PropertyValueConverters
=> Factory.GetInstance();
internal static IPublishedModelFactory PublishedModelFactory
=> Factory.GetInstance();
public static IServerMessenger ServerMessenger
=> Factory.GetInstance();
public static IServerRegistrar ServerRegistrar
=> Factory.GetInstance();
public static ICultureDictionaryFactory CultureDictionaryFactory
=> Factory.GetInstance();
public static AppCaches AppCaches
=> Factory.GetInstance();
public static ServiceContext Services
=> Factory.GetInstance();
public static IScopeProvider ScopeProvider
=> Factory.GetInstance();
public static ISqlContext SqlContext
=> Factory.GetInstance();
public static IPublishedContentTypeFactory PublishedContentTypeFactory
=> Factory.GetInstance();
public static IPublishedValueFallback PublishedValueFallback
=> _publishedValueFallback ?? Factory.GetInstance() ?? new NoopPublishedValueFallback();
public static IVariationContextAccessor VariationContextAccessor
=> Factory.GetInstance();
#endregion
}
}