diff --git a/src/Umbraco.Core/ApplicationContext.cs b/src/Umbraco.Core/ApplicationContext.cs index d29bd99438..3e8982d8a7 100644 --- a/src/Umbraco.Core/ApplicationContext.cs +++ b/src/Umbraco.Core/ApplicationContext.cs @@ -4,7 +4,6 @@ using System.Threading; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Services; using Umbraco.Core.Sync; @@ -66,43 +65,10 @@ namespace Umbraco.Core Initialize(); } - /// - /// Sets and/or ensures that a global application context exists. - /// - /// The application context instance. - /// A value indicating whether to replace the existing context, if any. - /// The current global application context. - /// This is NOT thread safe. For Unit Tests only. - public static ApplicationContext EnsureContext(ApplicationContext appContext, bool replaceContext) - { - if (Current != null && replaceContext == false) - return Current; - - return Current = appContext; - } - /// - /// Sets and/or ensures that a global application context exists. + /// Gets the current global application context. /// - /// A cache helper. - /// A logger. - /// A database context. - /// A service context. - /// A value indicating whether to replace the existing context, if any. - /// The current global application context. - /// This is NOT thread safe. For Unit Tests only. - public static ApplicationContext EnsureContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, ProfilingLogger logger, bool replaceContext) - { - if (Current != null && replaceContext == false) - return Current; - - return Current = new ApplicationContext(dbContext, serviceContext, cache, logger); - } - - /// - /// Gets the current global application context. - /// - public static ApplicationContext Current { get; internal set; } + public static ApplicationContext Current => DependencyInjection.Current.ApplicationContext; // fixme - obsolete /// /// Returns the application wide cache accessor diff --git a/src/Umbraco.Core/CoreRuntime.cs b/src/Umbraco.Core/CoreRuntime.cs index 187e11fb20..ad46bbef41 100644 --- a/src/Umbraco.Core/CoreRuntime.cs +++ b/src/Umbraco.Core/CoreRuntime.cs @@ -16,7 +16,6 @@ using Umbraco.Core.Logging; using Umbraco.Core.Manifest; using Umbraco.Core.Models.Mapping; using Umbraco.Core.Models.PublishedContent; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence.Migrations; using Umbraco.Core.Plugins; using Umbraco.Core.PropertyEditors; @@ -36,11 +35,10 @@ namespace Umbraco.Core public class CoreRuntime : IRuntime { private BootLoader _bootLoader; - private DisposableTimer _timer; + // fixme cleanup these private IServiceContainer _appStartupEvtContainer; - private bool _isInitialized; private bool _isStarted; private bool _isComplete; @@ -78,7 +76,17 @@ namespace Umbraco.Core private RuntimeState _state; // fixme what about web?! - // fixme - temp + /// + /// Initializes a new instance of the class. + /// + /// The Umbraco HttpApplication. + public CoreRuntime(UmbracoApplicationBase umbracoApplication) + { + if (umbracoApplication == null) throw new ArgumentNullException(nameof(umbracoApplication)); + UmbracoApplication = umbracoApplication; + } + + /// public virtual void Boot(ServiceContainer container) { // create and register essential stuff @@ -92,6 +100,9 @@ namespace Umbraco.Core // then compose Compose(container); + // fixme! + Compose1(container); + // the boot loader boots using a container scope, so anything that is PerScope will // be disposed after the boot loader has booted, and anything else will remain. // note that this REQUIRES that perWebRequestScope has NOT been enabled yet, else @@ -129,16 +140,18 @@ namespace Umbraco.Core protected virtual void Compose1(ServiceContainer container) { - // fixme need to cleanup below + ServiceProvider = new ActivatorServiceProvider(); + + //create the plugin manager + //TODO: this is currently a singleton but it would be better if it weren't. Unfortunately the only way to get + // rid of this singleton would be to put it into IoC and then use the ServiceLocator pattern. + PluginManager.Current = PluginManager = Current.PluginManager; //new PluginManager(ApplicationCache.RuntimeCache, ProfilingLogger, true); //TODO: Don't think we'll need this when the resolvers are all container resolvers container.RegisterSingleton(); container.RegisterSingleton(); container.Register(factory => FileSystemProviderManager.Current.GetFileSystemProvider()); - } - protected virtual void Compose2(ServiceContainer container) - { // fixme - should we capture Logger, etc here or use factory? // register manifest builder, will be injected in eg PropertyEditorCollectionBuilder @@ -163,17 +176,18 @@ namespace Umbraco.Core // register a server registrar, by default it's the db registrar unless the dev // has the legacy dist calls enabled - fixme - should obsolete the legacy thing - container.RegisterSingleton(_ => UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled + container.RegisterSingleton(factory => UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled ? (IServerRegistrar)new ConfigServerRegistrar(UmbracoConfig.For.UmbracoSettings()) : (IServerRegistrar)new DatabaseServerRegistrar( - new Lazy(() => ApplicationContext.Services.ServerRegistrationService), + new Lazy(() => factory.GetInstance().Services.ServerRegistrationService), new DatabaseServerRegistrarOptions())); // by default we'll use the database server messenger with default options (no callbacks), // this will be overridden in the web startup // fixme - painful, have to take care of lifetime! - we CANNOT ask users to remember! // fixme - same issue with PublishedContentModelFactory and many more, I guess! - container.RegisterSingleton(_ => new DatabaseServerMessenger(ApplicationContext, true, new DatabaseServerMessengerOptions())); + container.RegisterSingleton(factory + => new DatabaseServerMessenger(factory.GetInstance(), true, new DatabaseServerMessengerOptions())); CacheRefresherCollectionBuilder.Register(container) .AddProducer(factory => factory.GetInstance().ResolveCacheRefreshers()); @@ -198,6 +212,11 @@ namespace Umbraco.Core container.RegisterSingleton(); } + /// + /// Gets the Umbraco HttpApplication. + /// + protected UmbracoApplicationBase UmbracoApplication { get; } + #region Locals protected ILogger Logger { get; private set; } @@ -213,6 +232,8 @@ namespace Umbraco.Core #region Getters + // getters can be implemented by runtimes inheriting from CoreRuntime + protected virtual IEnumerable GetComponentTypes() => Current.PluginManager.ResolveTypes(); protected virtual IProfiler GetProfiler() => new LogProfiler(Logger); @@ -237,12 +258,12 @@ namespace Umbraco.Core // tries to connect to db (if configured) private void EnsureDatabaseConnection() { - if (ApplicationContext.IsConfigured == false) return; - if (ApplicationContext.DatabaseContext.IsDatabaseConfigured == false) return; + if (Current.ApplicationContext.IsConfigured == false) return; + if (Current.ApplicationContext.DatabaseContext.IsDatabaseConfigured == false) return; for (var i = 0; i < 5; i++) { - if (ApplicationContext.DatabaseContext.CanConnect) return; + if (Current.ApplicationContext.DatabaseContext.CanConnect) return; Thread.Sleep(1000); } @@ -257,7 +278,8 @@ namespace Umbraco.Core //foreach (var m in ApplicationEventsResolver.Current.ApplicationEventHandlers.OfType()) foreach (var m in Container.GetAllInstances()) { - m.ConfigureMappings(configuration, ApplicationContext); + Logger.Debug("FIXME " + m.GetType().FullName); + m.ConfigureMappings(configuration, Current.ApplicationContext); } }); } @@ -277,30 +299,11 @@ namespace Umbraco.Core // FIXME everything below needs to be sorted out! - protected ApplicationContext ApplicationContext { get; private set; } - - protected CacheHelper ApplicationCache { get; private set; } - - protected UmbracoApplicationBase UmbracoApplication { get; } protected ServiceContainer Container => Current.Container; // fixme kill protected IServiceProvider ServiceProvider { get; private set; } - public CoreRuntime(UmbracoApplicationBase umbracoApplication) - { - if (umbracoApplication == null) throw new ArgumentNullException("umbracoApplication"); - UmbracoApplication = umbracoApplication; - } - - internal CoreRuntime(UmbracoApplicationBase umbracoApplication, ProfilingLogger logger) - { - if (umbracoApplication == null) throw new ArgumentNullException("umbracoApplication"); - if (logger == null) throw new ArgumentNullException("logger"); - UmbracoApplication = umbracoApplication; - ProfilingLogger = logger; - } - public virtual IRuntime Initialize() { if (_isInitialized) @@ -312,22 +315,9 @@ namespace Umbraco.Core string.Format("Umbraco {0} application starting on {1}", UmbracoVersion.GetSemanticVersion().ToSemanticString(), NetworkHelper.MachineName), "Umbraco application startup complete"); - ServiceProvider = new ActivatorServiceProvider(); - - //create the plugin manager - //TODO: this is currently a singleton but it would be better if it weren't. Unfortunately the only way to get - // rid of this singleton would be to put it into IoC and then use the ServiceLocator pattern. - PluginManager.Current = PluginManager = Current.PluginManager; //new PluginManager(ApplicationCache.RuntimeCache, ProfilingLogger, true); // register - Compose1(Container); - - //set the singleton resolved from the core container - // fixme - last thing to understand before we merge the two Compose() methods! - ApplicationContext.Current = ApplicationContext = Container.GetInstance(); - - // register - why 2? - Compose2(Container); + //Compose1(Container); //TODO: Remove these for v8! LegacyPropertyEditorIdToAliasConverter.CreateMappingsForCoreEditors(); @@ -356,7 +346,7 @@ namespace Umbraco.Core //only log if more than 150ms 150)) { - x.OnApplicationInitialized(UmbracoApplication, ApplicationContext); + x.OnApplicationInitialized(UmbracoApplication, Current.ApplicationContext); } } catch (Exception ex) @@ -394,7 +384,7 @@ namespace Umbraco.Core //only log if more than 150ms 150)) { - x.OnApplicationStarting(UmbracoApplication, ApplicationContext); + x.OnApplicationStarting(UmbracoApplication, Current.ApplicationContext); } } catch (Exception ex) @@ -432,7 +422,7 @@ namespace Umbraco.Core //This is a special case for the user service, we need to tell it if it's an upgrade, if so we need to ensure that // exceptions are bubbled up if a user is attempted to be persisted during an upgrade (i.e. when they auth to login) - ((UserService) ApplicationContext.Services.UserService).IsUpgrading = true; + ((UserService) Current.ApplicationContext.Services.UserService).IsUpgrading = true; @@ -447,7 +437,7 @@ namespace Umbraco.Core //only log if more than 150ms 150)) { - x.OnApplicationStarted(UmbracoApplication, ApplicationContext); + x.OnApplicationStarted(UmbracoApplication, Current.ApplicationContext); } } catch (Exception ex) @@ -472,20 +462,15 @@ namespace Umbraco.Core _isComplete = true; // we're ready to serve content! - ApplicationContext.IsReady = true; + Current.ApplicationContext.IsReady = true; //stop the timer and log the output _timer.Dispose(); return this; } - - /// - /// Freeze resolution to not allow Resolvers to be modified - /// protected virtual void FreezeResolution() { - Resolution.Freeze(); } } } diff --git a/src/Umbraco.Core/DependencyInjection/Current.cs b/src/Umbraco.Core/DependencyInjection/Current.cs index be20a65aad..861156200e 100644 --- a/src/Umbraco.Core/DependencyInjection/Current.cs +++ b/src/Umbraco.Core/DependencyInjection/Current.cs @@ -47,6 +47,7 @@ namespace Umbraco.Core.DependencyInjection _logger = null; _profiler = null; _profilingLogger = null; + _applicationContext = null; Resetted?.Invoke(null, EventArgs.Empty); } @@ -55,6 +56,18 @@ namespace Umbraco.Core.DependencyInjection #region Getters + // fixme - refactor + // some of our tests want to *set* the current application context and bypass the container + // so for the time being we support it, however we should fix our tests + + private static ApplicationContext _applicationContext; + + public static ApplicationContext ApplicationContext + { + get { return _applicationContext ?? (_applicationContext = Container.GetInstance()); } + set { _applicationContext = value; } + } + public static PluginManager PluginManager => Container.GetInstance(); diff --git a/src/Umbraco.Core/ObjectResolution/Resolution.cs b/src/Umbraco.Core/ObjectResolution/Resolution.cs deleted file mode 100644 index 192d411683..0000000000 --- a/src/Umbraco.Core/ObjectResolution/Resolution.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System; -using System.Threading; -using Umbraco.Core.Logging; - -namespace Umbraco.Core.ObjectResolution -{ - // fixme - // this is the last bit that needs to go - // however, if it goes, we're missing Resolution.Frozen even which is used here and there - // => how can we do it? - - /// - /// Represents the status of objects resolution. - /// - /// - /// Before resolution is frozen it is possible to access its configuration, but not to get values. - /// Once resolution is frozen, it is not possible to access its configuration anymore, but it is possible to get values. - /// - internal static class Resolution - { - private static readonly ReaderWriterLockSlim ConfigurationLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); - private volatile static bool _isFrozen; - - /// - /// Occurs when resolution is frozen. - /// - /// Occurs only once, since resolution can be frozen only once. - public static event EventHandler Frozen; - - /// - /// Gets or sets a value indicating whether resolution of objects is frozen. - /// - // internal for unit tests, use ReadFrozen if you want to be sure - internal static bool IsFrozen - { - get - { - using (new ReadLock(ConfigurationLock)) - { - return _isFrozen; - } - } - } - - public static IDisposable Reader(bool canReadUnfrozen = false) - { - IDisposable l = new ReadLock(ConfigurationLock); - if (canReadUnfrozen || _isFrozen) return l; - - l.Dispose(); - throw new InvalidOperationException("Resolution is not frozen, it is not yet possible to get values from it."); - } - - /// - /// Returns a disposable object that represents safe access to unfrozen resolution configuration. - /// - /// Should be used in a using(Resolution.Configuration) { ... } mode. - public static IDisposable Configuration - { - get - { - IDisposable l = new WriteLock(ConfigurationLock); - if (_isFrozen == false) return l; - - l.Dispose(); - throw new InvalidOperationException("Resolution is frozen, it is not possible to configure it anymore."); - } - } - - // NOTE - the ugly code below exists only because of umbraco.BusinessLogic.Actions.Action.ReRegisterActionsAndHandlers - // which wants to re-register actions and handlers instead of properly restarting the application. Don't even think - // about using it for anything else. Also, while the backdoor is open, the resolution system is locked so nothing - // can work properly => deadlocks. Therefore, open the backdoor, do resolution changes EXCLUSIVELY, and close the door! - - /// - /// Freezes resolution. - /// - /// resolution is already frozen. - public static void Freeze() - { - LogHelper.Debug(typeof (Resolution), "Freezing resolution"); - - using (new WriteLock(ConfigurationLock)) - { - if (_isFrozen) - throw new InvalidOperationException("Resolution is frozen. It is not possible to freeze it again."); - - _isFrozen = true; - } - - LogHelper.Debug(typeof(Resolution), "Resolution is frozen"); - - if (Frozen == null) return; - - try - { - Frozen(null, null); - } - catch (Exception e) - { - LogHelper.Error(typeof (Resolution), "Exception in Frozen event handler.", e); - throw; - } - } - - /// - /// Resets resolution, ie unfreezes it and clears Frozen event. - /// - /// To be used in unit tests. - internal static void Reset() - { - LogHelper.Debug(typeof(Resolution), "Resetting resolution"); - - /* - var trace = new System.Diagnostics.StackTrace(); - var testing = trace.GetFrames().Any(frame => - frame.GetMethod().DeclaringType.FullName.StartsWith("Umbraco.Tests")); - if (testing == false) - throw new InvalidOperationException("Only unit tests can reset configuration."); - */ - - using (new WriteLock(ConfigurationLock)) - { - _isFrozen = false; - } - Frozen = null; - } - } -} diff --git a/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs b/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs index e3a82f41c6..556c0e73a3 100644 --- a/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs +++ b/src/Umbraco.Core/Sync/ApplicationUrlHelper.cs @@ -4,7 +4,6 @@ using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.DependencyInjection; using Umbraco.Core.IO; -using Umbraco.Core.ObjectResolution; namespace Umbraco.Core.Sync { @@ -28,7 +27,7 @@ namespace Umbraco.Core.Sync /// in config files but is determined programmatically. /// Must be assigned before resolution is frozen. /// - public static Func ApplicationUrlProvider + public static Func ApplicationUrlProvider // FIXME need another way to do it, eg an interface, injected! { get { @@ -36,10 +35,7 @@ namespace Umbraco.Core.Sync } set { - using (Resolution.Configuration) - { - _applicationUrlProvider = value; - } + _applicationUrlProvider = value; } } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index c83be03233..fccf2442cd 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -1143,7 +1143,6 @@ - diff --git a/src/Umbraco.Tests/ApplicationUrlHelperTests.cs b/src/Umbraco.Tests/ApplicationUrlHelperTests.cs index 6907b68cf9..0a6e2dd085 100644 --- a/src/Umbraco.Tests/ApplicationUrlHelperTests.cs +++ b/src/Umbraco.Tests/ApplicationUrlHelperTests.cs @@ -8,7 +8,6 @@ using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Logging; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Profiling; using Umbraco.Core.Sync; using Umbraco.Tests.TestHelpers; diff --git a/src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs b/src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs index 935bd50336..626f222ef6 100644 --- a/src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs +++ b/src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs @@ -8,7 +8,6 @@ using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.DependencyInjection; using Umbraco.Core.Logging; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Sync; namespace Umbraco.Tests.Cache.DistributedCache diff --git a/src/Umbraco.Tests/DependencyInjection/ResolverBaseTest.cs b/src/Umbraco.Tests/DependencyInjection/ResolverBaseTest.cs index 2748ab83a5..29f6ae80a4 100644 --- a/src/Umbraco.Tests/DependencyInjection/ResolverBaseTest.cs +++ b/src/Umbraco.Tests/DependencyInjection/ResolverBaseTest.cs @@ -5,7 +5,6 @@ using NUnit.Framework; using Umbraco.Core.Cache; using Umbraco.Core.DependencyInjection; using Umbraco.Core.Logging; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Plugins; namespace Umbraco.Tests.DependencyInjection @@ -31,7 +30,6 @@ namespace Umbraco.Tests.DependencyInjection [TearDown] public void TearDown() { - Resolution.Reset(); Current.Reset(); } diff --git a/src/Umbraco.Tests/Macros/MacroTests.cs b/src/Umbraco.Tests/Macros/MacroTests.cs index 88d4282c7d..14f857db24 100644 --- a/src/Umbraco.Tests/Macros/MacroTests.cs +++ b/src/Umbraco.Tests/Macros/MacroTests.cs @@ -13,9 +13,11 @@ using umbraco; using Umbraco.Core.Configuration; using Umbraco.Core.Models; using Umbraco.Tests.TestHelpers; +using Umbraco.Web; using Umbraco.Web.Macros; using File = System.IO.File; using Macro = umbraco.cms.businesslogic.macro.Macro; +using Current = Umbraco.Core.DependencyInjection.Current; namespace Umbraco.Tests.Macros { @@ -32,7 +34,7 @@ namespace Umbraco.Tests.Macros new StaticCacheProvider(), new NullCacheProvider(), new IsolatedRuntimeCache(type => new ObjectCacheRuntimeCacheProvider())); - ApplicationContext.Current = new ApplicationContext(cacheHelper, new ProfilingLogger(Mock.Of(), Mock.Of())); + Current.ApplicationContext = new ApplicationContext(cacheHelper, new ProfilingLogger(Mock.Of(), Mock.Of())); UmbracoConfig.For.SetUmbracoSettings(SettingsForTests.GetDefault()); } @@ -40,9 +42,9 @@ namespace Umbraco.Tests.Macros [TearDown] public void TearDown() { - ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearAllCache(); - ApplicationContext.Current.DisposeIfDisposable(); - ApplicationContext.Current = null; + Current.ApplicationContext.ApplicationCache.RuntimeCache.ClearAllCache(); + Current.ApplicationContext.DisposeIfDisposable(); + Current.Reset(); } [TestCase("123", "IntProp", typeof(int))] diff --git a/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs b/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs index 860c9e1ce9..6522e3f78f 100644 --- a/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs +++ b/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs @@ -8,7 +8,6 @@ using Moq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Logging; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Migrations; using Umbraco.Core.Persistence.SqlSyntax; diff --git a/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs index 50be7dc207..55e974c140 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs @@ -11,7 +11,6 @@ using SQLCE4Umbraco; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Migrations.Initial; using Umbraco.Core.Persistence.SqlSyntax; @@ -70,8 +69,6 @@ namespace Umbraco.Tests.Migrations.Upgrades //Get the connectionstring settings from config var settings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName]; - Resolution.Freeze(); - //Create the Sql CE database using (var engine = new SqlCeEngine(settings.ConnectionString)) { @@ -83,8 +80,6 @@ namespace Umbraco.Tests.Migrations.Upgrades [TearDown] public virtual void TearDown() { - Resolution.Reset(); - TestHelper.CleanContentDirectories(); Path = TestHelper.CurrentAssemblyDirectory; diff --git a/src/Umbraco.Tests/MockTests.cs b/src/Umbraco.Tests/MockTests.cs index 6858c615f7..f39171fc0c 100644 --- a/src/Umbraco.Tests/MockTests.cs +++ b/src/Umbraco.Tests/MockTests.cs @@ -82,31 +82,6 @@ namespace Umbraco.Tests Assert.Pass(); } - [Test] - public void Can_Assign_App_Context_Singleton() - { - var appCtx = new ApplicationContext( - CacheHelper.CreateDisabledCacheHelper(), - new ProfilingLogger(Mock.Of(), Mock.Of())); - var result = ApplicationContext.EnsureContext(appCtx, true); - Assert.AreEqual(appCtx, result); - } - - [Test] - public void Does_Not_Overwrite_App_Context_Singleton() - { - ApplicationContext.EnsureContext( - new ApplicationContext( - CacheHelper.CreateDisabledCacheHelper(), - new ProfilingLogger(Mock.Of(), Mock.Of())), true); - - var appCtx = new ApplicationContext( - CacheHelper.CreateDisabledCacheHelper(), - new ProfilingLogger(Mock.Of(), Mock.Of())); - var result = ApplicationContext.EnsureContext(appCtx, false); - Assert.AreNotEqual(appCtx, result); - } - [Test] public void Can_Get_Umbraco_Context() { diff --git a/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs b/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs index 1f46cf7654..4fbfeb305e 100644 --- a/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs +++ b/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs @@ -10,7 +10,6 @@ using Umbraco.Core.DependencyInjection; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; using Umbraco.Web.Models; diff --git a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs index b6c0110019..a8509145db 100644 --- a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs @@ -5,6 +5,7 @@ using Moq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; +using Umbraco.Core.DependencyInjection; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Profiling; @@ -109,7 +110,7 @@ namespace Umbraco.Tests.PropertyEditors { IsReady = true }; - ApplicationContext.Current = appContext; + Current.ApplicationContext = appContext; var defaultVals = new Dictionary(); var persisted = new PreValueCollection(new Dictionary diff --git a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs index 973de54c22..e0686a5efb 100644 --- a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs @@ -8,7 +8,6 @@ using Umbraco.Core.DependencyInjection; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Strings; using Umbraco.Tests.TestHelpers; diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs index f3d6955591..792ad788fd 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs @@ -77,8 +77,7 @@ namespace Umbraco.Tests.PublishedContent base.TearDown(); PluginManager.Current = _pluginManager; - ApplicationContext.Current.DisposeIfDisposable(); - ApplicationContext.Current = null; + Core.DependencyInjection.Current.Reset(); } [Test] diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs index 8cb3f2cf05..39d59ac1b4 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs @@ -59,8 +59,7 @@ namespace Umbraco.Tests.PublishedContent { base.TearDown(); PluginManager.Current = _pluginManager; - ApplicationContext.Current.DisposeIfDisposable(); - ApplicationContext.Current = null; + Core.DependencyInjection.Current.Reset(); } protected override void FreezeResolution() diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs index c4fbc775f3..8d329a7a2a 100644 --- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs +++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs @@ -1,5 +1,6 @@ using System.Web.Mvc; using System.Web.Routing; +using LightInject; using Moq; using NUnit.Framework; using Umbraco.Core; @@ -29,13 +30,32 @@ namespace Umbraco.Tests.Routing SettingsForTests.UmbracoPath = "~/umbraco"; - var webBoot = new WebRuntime(new UmbracoApplication(), new ProfilingLogger(Mock.Of(), Mock.Of()), true); + var webBoot = new TestRuntime(new UmbracoApplication()); //webBoot.Initialize(); //webBoot.Startup(null); -> don't call startup, we don't want any other application event handlers to bind for this test. //webBoot.Complete(null); webBoot.CreateRoutes(); } + public class TestRuntime : WebRuntime + { + public TestRuntime(UmbracoApplicationBase umbracoApplication) + : base(umbracoApplication) + { } + + public override void Boot(ServiceContainer container) + { + // do it before anything else - this is the only place where it's possible + var logger = Mock.Of(); + container.RegisterInstance(logger); + var profiler = Mock.Of(); + container.RegisterInstance(profiler); + container.RegisterInstance(new ProfilingLogger(logger, profiler)); + + base.Boot(container); + } + } + protected override void FreezeResolution() { // set the default RenderMvcController diff --git a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs index 612ea9d54d..fd7bd8beba 100644 --- a/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs +++ b/src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs @@ -46,9 +46,23 @@ namespace Umbraco.Tests.Runtimes // test runtime - inheriting from core runtime public class TestRuntime : CoreRuntime { - public TestRuntime(UmbracoApplicationBase umbracoApplication, ProfilingLogger logger) - : base(umbracoApplication, logger) - { } + private readonly ProfilingLogger _proflog; + + public TestRuntime(UmbracoApplicationBase umbracoApplication, ProfilingLogger proflog) + : base(umbracoApplication) + { + _proflog = proflog; + } + + public override void Boot(ServiceContainer container) + { + // do it before anything else - this is the only place where it's possible + container.RegisterInstance(_proflog.Logger); + container.RegisterInstance(_proflog.Profiler); + container.RegisterInstance(_proflog); + + base.Boot(container); + } protected override void Compose1(ServiceContainer container) { diff --git a/src/Umbraco.Tests/Strings/DefaultShortStringHelperTests.cs b/src/Umbraco.Tests/Strings/DefaultShortStringHelperTests.cs index 278efe682a..ae16dc7184 100644 --- a/src/Umbraco.Tests/Strings/DefaultShortStringHelperTests.cs +++ b/src/Umbraco.Tests/Strings/DefaultShortStringHelperTests.cs @@ -11,7 +11,6 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.DependencyInjection; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Strings; using Umbraco.Tests.TestHelpers; diff --git a/src/Umbraco.Tests/Strings/StringExtensionsTests.cs b/src/Umbraco.Tests/Strings/StringExtensionsTests.cs index 5d21eacf1b..a6d30836bf 100644 --- a/src/Umbraco.Tests/Strings/StringExtensionsTests.cs +++ b/src/Umbraco.Tests/Strings/StringExtensionsTests.cs @@ -5,7 +5,6 @@ using LightInject; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.DependencyInjection; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Strings; namespace Umbraco.Tests.Strings diff --git a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs index 5d6196d0c9..2c28b31821 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs @@ -12,7 +12,6 @@ using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models.Mapping; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Persistence.UnitOfWork; @@ -82,8 +81,7 @@ namespace Umbraco.Tests.TestHelpers TestHelper.CleanUmbracoSettingsConfig(); // reset the app context, this should reset most things that require resetting like ALL resolvers - ApplicationContext.Current.DisposeIfDisposable(); - ApplicationContext.Current = null; + Core.DependencyInjection.Current.Reset(); // reset plugin manager ResetPluginManager(); @@ -208,7 +206,7 @@ namespace Umbraco.Tests.TestHelpers private void SetupApplicationContext() { var applicationContext = CreateApplicationContext(); - ApplicationContext.Current = applicationContext; + Container.Register(_ => applicationContext); } /// @@ -269,7 +267,6 @@ namespace Umbraco.Tests.TestHelpers /// protected virtual void FreezeResolution() { - Resolution.Freeze(); } protected ApplicationContext ApplicationContext => ApplicationContext.Current; diff --git a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs index 49c7c8cf1d..5dd646ec07 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs @@ -5,7 +5,6 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Logging; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Profiling; @@ -52,7 +51,6 @@ namespace Umbraco.Tests.TestHelpers var pocoDataFactory = new FluentPocoDataFactory((type, iPocoDataFactory) => new PocoDataBuilder(type, mappers).Init()); SqlContext = new SqlContext(sqlSyntax, pocoDataFactory, DatabaseType.SQLCe); - Resolution.Freeze(); SetUp(); } @@ -62,7 +60,6 @@ namespace Umbraco.Tests.TestHelpers [TearDown] public virtual void TearDown() { - Resolution.Reset(); //MappingResolver.Reset(); PluginManager.Current = null; Current.Reset(); diff --git a/src/Umbraco.Tests/TryConvertToTests.cs b/src/Umbraco.Tests/TryConvertToTests.cs index 56af5d6d42..4834776956 100644 --- a/src/Umbraco.Tests/TryConvertToTests.cs +++ b/src/Umbraco.Tests/TryConvertToTests.cs @@ -2,7 +2,6 @@ using LightInject; using NUnit.Framework; using Umbraco.Core; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Strings; using Umbraco.Tests.TestHelpers; using Umbraco.Core.DependencyInjection; diff --git a/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs b/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs index 90cec3c5bd..2121a639c1 100644 --- a/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs +++ b/src/Umbraco.Tests/UmbracoExamine/ExamineBaseTest.cs @@ -5,7 +5,6 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.DependencyInjection; using Umbraco.Core.Logging; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Profiling; using Umbraco.Core.Strings; diff --git a/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs b/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs index 4d4fbd4fb8..6bf5747ad7 100644 --- a/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs @@ -23,7 +23,7 @@ using Umbraco.Web.Mvc; using Umbraco.Web.PublishedCache; using Umbraco.Web.Routing; using Umbraco.Web.Security; -using Current = Umbraco.Web.Current; +using Current = Umbraco.Core.DependencyInjection.Current; namespace Umbraco.Tests.Web.Mvc { @@ -33,7 +33,7 @@ namespace Umbraco.Tests.Web.Mvc [SetUp] public void SetUp() { - Current.UmbracoContextAccessor = new TestUmbracoContextAccessor(); + Umbraco.Web.Current.UmbracoContextAccessor = new TestUmbracoContextAccessor(); } [TearDown] @@ -71,7 +71,7 @@ namespace Umbraco.Tests.Web.Mvc CacheHelper.CreateDisabledCacheHelper(), new ProfilingLogger(Mock.Of(), Mock.Of())); - ApplicationContext.EnsureContext(appCtx, true); + Current.ApplicationContext = appCtx; // FIXME horrible var umbCtx = UmbracoContext.EnsureContext( new Mock().Object, appCtx, diff --git a/src/Umbraco.Web/Current.cs b/src/Umbraco.Web/Current.cs index 0056c4da68..c73b886c3b 100644 --- a/src/Umbraco.Web/Current.cs +++ b/src/Umbraco.Web/Current.cs @@ -199,6 +199,8 @@ namespace Umbraco.Web // proxy Core for convenience + public static ApplicationContext ApplicationContext => CoreCurrent.ApplicationContext; + public static PluginManager PluginManager => CoreCurrent.PluginManager; public static UrlSegmentProviderCollection UrlSegmentProviders => CoreCurrent.UrlSegmentProviders; diff --git a/src/Umbraco.Web/Media/ThumbnailProviders/FileExtensionIconThumbnailProvider.cs b/src/Umbraco.Web/Media/ThumbnailProviders/FileExtensionIconThumbnailProvider.cs index 1350f32318..6acdb0d75a 100644 --- a/src/Umbraco.Web/Media/ThumbnailProviders/FileExtensionIconThumbnailProvider.cs +++ b/src/Umbraco.Web/Media/ThumbnailProviders/FileExtensionIconThumbnailProvider.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Text; using Umbraco.Core.DependencyInjection; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.IO; namespace Umbraco.Web.Media.ThumbnailProviders diff --git a/src/Umbraco.Web/Media/ThumbnailProviders/ImageThumbnailProvider.cs b/src/Umbraco.Web/Media/ThumbnailProviders/ImageThumbnailProvider.cs index 9eb992b9cd..4d5f3d0b1e 100644 --- a/src/Umbraco.Web/Media/ThumbnailProviders/ImageThumbnailProvider.cs +++ b/src/Umbraco.Web/Media/ThumbnailProviders/ImageThumbnailProvider.cs @@ -6,8 +6,6 @@ using System.Text; using Umbraco.Core; using Umbraco.Core.DependencyInjection; using Umbraco.Core.IO; -using Umbraco.Core.ObjectResolution; -using Umbraco.Core.IO; namespace Umbraco.Web.Media.ThumbnailProviders { diff --git a/src/Umbraco.Web/Media/ThumbnailProviders/MediaTypeIconThumbnailProvider.cs b/src/Umbraco.Web/Media/ThumbnailProviders/MediaTypeIconThumbnailProvider.cs index 3e6f10dfe2..d9344864e7 100644 --- a/src/Umbraco.Web/Media/ThumbnailProviders/MediaTypeIconThumbnailProvider.cs +++ b/src/Umbraco.Web/Media/ThumbnailProviders/MediaTypeIconThumbnailProvider.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Text; using Umbraco.Core.DependencyInjection; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.IO; namespace Umbraco.Web.Media.ThumbnailProviders diff --git a/src/Umbraco.Web/PublishedCache/NuCache/FacadeService.cs b/src/Umbraco.Web/PublishedCache/NuCache/FacadeService.cs index b247c7204a..443a3307eb 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/FacadeService.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/FacadeService.cs @@ -14,7 +14,6 @@ using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; using Umbraco.Core.Models.PublishedContent; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Repositories; @@ -141,13 +140,10 @@ namespace Umbraco.Web.PublishedCache.NuCache _domainStore = new SnapDictionary(); - if (Resolution.IsFrozen) - OnResolutionFrozen(); - else - Resolution.Frozen += (sender, args) => OnResolutionFrozen(); + LoadCaches(); } - private void OnResolutionFrozen() + private void LoadCaches() { lock (_storesLock) { diff --git a/src/Umbraco.Web/PublishedCache/NuCache/NuCacheComponent.cs b/src/Umbraco.Web/PublishedCache/NuCache/NuCacheComponent.cs new file mode 100644 index 0000000000..a74f5d7967 --- /dev/null +++ b/src/Umbraco.Web/PublishedCache/NuCache/NuCacheComponent.cs @@ -0,0 +1,32 @@ +using LightInject; +using Umbraco.Core; +using Umbraco.Core.Components; +using Umbraco.Core.DependencyInjection; +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence.UnitOfWork; +using Umbraco.Core.Services; + +namespace Umbraco.Web.PublishedCache.NuCache +{ + public class NuCacheComponent : UmbracoComponentBase, IUmbracoCoreComponent + { + public override void Compose(ServiceContainer container) + { + base.Compose(container); + + // register the NuCache facade service + container.RegisterSingleton(factory => new FacadeService( + new FacadeService.Options { FacadeCacheIsApplicationRequestCache = true }, + factory.GetInstance().MainDom, + factory.GetInstance(), + factory.GetInstance(), + factory.GetInstance(), + factory.GetInstance())); + } + + public void Initialize(IFacadeService service) + { + // nothing - this just ensures that the service is created at boot time + } + } +} diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/RoutesCache.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/RoutesCache.cs index e2d0846eb2..b6a788fbef 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/RoutesCache.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/RoutesCache.cs @@ -3,7 +3,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; -using Umbraco.Core.ObjectResolution; namespace Umbraco.Web.PublishedCache.XmlPublishedCache { diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlCacheComponent.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlCacheComponent.cs new file mode 100644 index 0000000000..9324fa35d1 --- /dev/null +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlCacheComponent.cs @@ -0,0 +1,32 @@ +using LightInject; +using Umbraco.Core.Cache; +using Umbraco.Core.Components; +using Umbraco.Core.Persistence.UnitOfWork; +using Umbraco.Core.Services; +using Umbraco.Core.Strings; +using Umbraco.Core.DependencyInjection; + +namespace Umbraco.Web.PublishedCache.XmlPublishedCache +{ + [DisableComponent] // is not enabled by default + public class XmlCacheComponent : UmbracoComponentBase, IUmbracoCoreComponent + { + public override void Compose(ServiceContainer container) + { + base.Compose(container); + + // register the XML facade service + container.RegisterSingleton(factory => new FacadeService( + factory.GetInstance(), + factory.GetInstance(), + factory.GetInstance().RequestCache, + factory.GetAllInstances(), + factory.GetInstance())); + } + + public void Initialize(IFacadeService service) + { + // nothing - this just ensures that the service is created at boot time + } + } +} diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStore.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStore.cs index 88078a3d56..dad048a7a1 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStore.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlStore.cs @@ -14,7 +14,6 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Rdbms; -using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Repositories; @@ -92,11 +91,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache InitializeFilePersister(); } - // need to wait for resolution to be frozen - if (Resolution.IsFrozen) - OnResolutionFrozen(testing, enableRepositoryEvents); - else - Resolution.Frozen += (sender, args) => OnResolutionFrozen(testing, enableRepositoryEvents); + Initialize(testing, enableRepositoryEvents); } // internal for unit tests @@ -169,7 +164,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache _released = (registered == false); } - private void OnResolutionFrozen(bool testing, bool enableRepositoryEvents) + private void Initialize(bool testing, bool enableRepositoryEvents) { if (testing == false || enableRepositoryEvents) InitializeRepositoryEvents(); diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 1bab99e1ef..0ecb89c00c 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -222,6 +222,7 @@ + @@ -267,6 +268,7 @@ + diff --git a/src/Umbraco.Web/WebRuntime.cs b/src/Umbraco.Web/WebRuntime.cs index 46b6faff91..660860ac9e 100644 --- a/src/Umbraco.Web/WebRuntime.cs +++ b/src/Umbraco.Web/WebRuntime.cs @@ -38,6 +38,7 @@ using Umbraco.Web.Editors; using Umbraco.Core.DependencyInjection; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.UnitOfWork; +using Umbraco.Core.Plugins; using Umbraco.Core.Services.Changes; using Umbraco.Web.Cache; using Umbraco.Web.DependencyInjection; @@ -56,25 +57,63 @@ namespace Umbraco.Web /// Represents the Web Umbraco runtime. /// /// On top of CoreRuntime, handles all of the web-related aspects of Umbraco (startup, etc). - public class WebRuntime : CoreRuntime + public class WebRuntime : CoreRuntime // fixme - probably crazy but... could it be a component?! { + /// + /// Initializes a new instance of the class. + /// + /// + public WebRuntime(UmbracoApplicationBase umbracoApplication) + : base(umbracoApplication) + { } + + /// public override void Boot(ServiceContainer container) { base.Boot(container); + + // that one must come *last* because there is no "request scope" during boot, + // and components are initialized within a scope so that anything they create + // that is per-scope is disposed one they have initialized. + container.EnablePerWebRequestScope(); + + // fixme - see compose + if it's here then components cannot change anything? + // should we use collections? eg MvcControllerCollection and ApiControllerCollection? + var pluginManager = container.GetInstance(); + container.EnableMvc(); // that one does enable PerWebRequest scope + container.RegisterMvcControllers(pluginManager, GetType().Assembly); + container.EnableWebApi(GlobalConfiguration.Configuration); + container.RegisterApiControllers(pluginManager, GetType().Assembly); } + /// public override void Terminate() { base.Terminate(); } + /// + public override void Compose(ServiceContainer container) + { + base.Compose(container); + + // fixme + var pluginManager = container.GetInstance(); + + // fixme - suspecting one of these to enable PerWebRequest scope + //container.EnableMvc(); // yes, that one! + //container.RegisterMvcControllers(pluginManager, GetType().Assembly); + //container.EnableWebApi(GlobalConfiguration.Configuration); + //container.RegisterApiControllers(pluginManager, GetType().Assembly); + } + protected override void Compose1(ServiceContainer container) { - base.Compose1(container); - // register model mappers container.RegisterFrom(); + base.Compose1(container); + // support web request scope // note: everything that is PerRequestLifeTime will be disposed by LightInject at the end of the request // fixme - temp - moved to... find it @@ -98,23 +137,6 @@ namespace Umbraco.Web // have to use the hybrid thing... container.RegisterSingleton(); - // register the XML facade service - //container.RegisterSingleton(factory => new PublishedCache.XmlPublishedCache.FacadeService( - // factory.GetInstance(), - // factory.GetInstance(), - // factory.GetInstance().RequestCache, - // factory.GetAllInstances(), - // factory.GetInstance())); - - // register the NuCache facade service - container.RegisterSingleton(factory => new PublishedCache.NuCache.FacadeService( - new PublishedCache.NuCache.FacadeService.Options { FacadeCacheIsApplicationRequestCache = true }, - factory.GetInstance().MainDom, - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance(), - factory.GetInstance())); - // register a per-request UmbracoContext object // no real need to be per request but assuming it is faster container.Register(factory => factory.GetInstance().UmbracoContext, new PerRequestLifeTime()); @@ -129,11 +151,6 @@ namespace Umbraco.Web container.RegisterSingleton(); container.RegisterSingleton(); - } - - protected override void Compose2(ServiceContainer container) - { - base.Compose2(container); // fixme moved too wtf //// IoC setup for LightInject for MVC/WebApi @@ -157,11 +174,12 @@ namespace Umbraco.Web if (UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled) { //set the legacy one by default - this maintains backwards compat - container.Register(_ => new BatchedWebServiceServerMessenger(() => + container.Register(factory => new BatchedWebServiceServerMessenger(() => { + var applicationContext = factory.GetInstance(); //we should not proceed to change this if the app/database is not configured since there will // be no user, plus we don't need to have server messages sent if this is the case. - if (ApplicationContext.IsConfigured && ApplicationContext.DatabaseContext.IsDatabaseConfigured) + if (applicationContext.IsConfigured && applicationContext.DatabaseContext.IsDatabaseConfigured) { //disable if they are not enabled if (UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled == false) @@ -171,7 +189,7 @@ namespace Umbraco.Web try { - var user = ApplicationContext.Services.UserService.GetUserById(UmbracoConfig.For.UmbracoSettings().DistributedCall.UserId); + var user = applicationContext.Services.UserService.GetUserById(UmbracoConfig.For.UmbracoSettings().DistributedCall.UserId); return new Tuple(user.Username, user.RawPasswordValue); } catch (Exception e) @@ -186,8 +204,8 @@ namespace Umbraco.Web } else { - container.Register(_ => new BatchedDatabaseServerMessenger( - ApplicationContext, + container.Register(factory => new BatchedDatabaseServerMessenger( + factory.GetInstance(), true, //Default options for web including the required callbacks to build caches new DatabaseServerMessengerOptions @@ -247,7 +265,7 @@ namespace Umbraco.Web .Append() .Append(); - Container.Register(); + container.Register(); ContentFinderCollectionBuilder.Register(container) // all built-in finders in the correct order, @@ -375,7 +393,7 @@ namespace Umbraco.Web $"umbraco-api-{meta.ControllerName}", url, // url to match new { controller = meta.ControllerName, id = UrlParameter.Optional }, - new[] { meta.ControllerNamespace }); + new[] { meta.ControllerNamespace }); if (route.DataTokens == null) // web api routes don't set the data tokens object route.DataTokens = new RouteValueDictionary(); route.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, "api"); //ensure the umbraco token is set @@ -398,20 +416,6 @@ namespace Umbraco.Web #endregion - public WebRuntime(UmbracoApplicationBase umbracoApplication) - : base(umbracoApplication) - { } - - /// - /// Constructor for unit tests, ensures some resolvers are not initialized - /// - /// - /// - /// - internal WebRuntime(UmbracoApplicationBase umbracoApplication, ProfilingLogger logger, bool isForTesting) - : base(umbracoApplication, logger) - { } - /// /// Initialize objects before anything during the boot cycle happens /// @@ -428,13 +432,15 @@ namespace Umbraco.Web base.Initialize(); - // fixme - only here so that everything above can have its OWN scope + // fixme - only here so that everything above can have its OWN scope => must come AFTER?? we have initialized all the components... OR?! + // so that should basically happen AFTER we have Compose() and Initialize() each component = wtf? // this is all completely fucked - Container.EnablePerWebRequestScope(); - Container.EnableMvc(); - Container.RegisterMvcControllers(PluginManager, GetType().Assembly); - Container.EnableWebApi(GlobalConfiguration.Configuration); - Container.RegisterApiControllers(PluginManager, GetType().Assembly); + //Container.EnablePerWebRequestScope(); // THAT ONE is causing the issue + // the rest is moving to Compose? + //Container.EnableMvc(); + //Container.RegisterMvcControllers(PluginManager, GetType().Assembly); + //Container.EnableWebApi(GlobalConfiguration.Configuration); + //Container.RegisterApiControllers(PluginManager, GetType().Assembly); //setup mvc and webapi services SetupMvcAndWebApi(); @@ -477,10 +483,10 @@ namespace Umbraco.Web //before we do anything, we'll ensure the umbraco context //see: http://issues.umbraco.org/issue/U4-1717 var httpContext = new HttpContextWrapper(UmbracoApplication.Context); - UmbracoContext.EnsureContext( - httpContext, ApplicationContext, + UmbracoContext.EnsureContext( // fixme - refactor! UmbracoContext & UmbracoRequestContext! + httpContext, Current.ApplicationContext, Current.FacadeService, - new WebSecurity(httpContext, ApplicationContext), + new WebSecurity(httpContext, Current.ApplicationContext), UmbracoConfig.For.UmbracoSettings(), Current.UrlProviders, false); @@ -500,7 +506,7 @@ namespace Umbraco.Web ConfigureGlobalFilters(); //set routes - CreateRoutes(); + CreateRoutes(); // fixme - throws, wtf?! base.Complete(afterComplete); @@ -544,7 +550,7 @@ namespace Umbraco.Web protected virtual void RebuildIndexes(bool onlyEmptyIndexes) { - if (ApplicationContext.IsConfigured == false || ApplicationContext.DatabaseContext.IsDatabaseConfigured == false) + if (Current.ApplicationContext.IsConfigured == false || Current.ApplicationContext.DatabaseContext.IsDatabaseConfigured == false) { return; }