Merge pull request #4577 from umbraco/temp8-contexts
Refactor UmbracoContext
This commit is contained in:
@@ -1,64 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract implementation of IDisposable.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is for objects that DO have unmanaged resources. Use <see cref="DisposableObjectSlim"/>
|
||||
/// for objects that do NOT have unmanaged resources, and avoid creating a finalizer.
|
||||
///
|
||||
/// Can also be used as a pattern for when inheriting is not possible.
|
||||
///
|
||||
/// See also: https://msdn.microsoft.com/en-us/library/b1yfkh5e%28v=vs.110%29.aspx
|
||||
/// See also: https://lostechies.com/chrispatterson/2012/11/29/idisposable-done-right/
|
||||
///
|
||||
/// Note: if an object's ctor throws, it will never be disposed, and so if that ctor
|
||||
/// has allocated disposable objects, it should take care of disposing them.
|
||||
/// </remarks>
|
||||
public abstract class DisposableObject : IDisposable
|
||||
{
|
||||
private readonly object _locko = new object();
|
||||
|
||||
// gets a value indicating whether this instance is disposed.
|
||||
// for internal tests only (not thread safe)
|
||||
public bool Disposed { get; private set; }
|
||||
|
||||
// implements IDisposable
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// finalizer
|
||||
~DisposableObject()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
// can happen if the object construction failed
|
||||
if (_locko == null)
|
||||
return;
|
||||
|
||||
lock (_locko)
|
||||
{
|
||||
if (Disposed) return;
|
||||
Disposed = true;
|
||||
}
|
||||
|
||||
DisposeUnmanagedResources();
|
||||
|
||||
if (disposing)
|
||||
DisposeResources();
|
||||
}
|
||||
|
||||
protected abstract void DisposeResources();
|
||||
|
||||
protected virtual void DisposeUnmanagedResources()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ namespace Umbraco.Core.Logging
|
||||
}
|
||||
|
||||
// a lightweight disposable timer
|
||||
private class LightDisposableTimer : DisposableObject
|
||||
private class LightDisposableTimer : DisposableObjectSlim
|
||||
{
|
||||
private readonly Action<long> _callback;
|
||||
private readonly Stopwatch _stopwatch = Stopwatch.StartNew();
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Umbraco.Core.Logging
|
||||
public void Stop(bool discardResults = false)
|
||||
{ }
|
||||
|
||||
private class VoidDisposable : DisposableObject
|
||||
private class VoidDisposable : DisposableObjectSlim
|
||||
{
|
||||
protected override void DisposeResources()
|
||||
{ }
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Persistence
|
||||
/// </remarks>
|
||||
// TODO: these comments are not true anymore
|
||||
// TODO: this class needs not be disposable!
|
||||
internal class UmbracoDatabaseFactory : DisposableObject, IUmbracoDatabaseFactory
|
||||
internal class UmbracoDatabaseFactory : DisposableObjectSlim, IUmbracoDatabaseFactory
|
||||
{
|
||||
private readonly Lazy<IMapperCollection> _mappers;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
@@ -561,7 +561,6 @@
|
||||
<Compile Include="DictionaryExtensions.cs" />
|
||||
<Compile Include="Dictionary\ICultureDictionary.cs" />
|
||||
<Compile Include="Dictionary\ICultureDictionaryFactory.cs" />
|
||||
<Compile Include="DisposableObject.cs" />
|
||||
<Compile Include="Logging\DisposableTimer.cs" />
|
||||
<Compile Include="EmailSender.cs" />
|
||||
<Compile Include="Enum.cs" />
|
||||
|
||||
@@ -4,11 +4,14 @@ using System.Threading;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Tests.Testing;
|
||||
using Umbraco.Tests.Testing.Objects.Accessors;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Cache;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web.Routing;
|
||||
@@ -148,8 +151,18 @@ namespace Umbraco.Tests.Cache
|
||||
|
||||
};
|
||||
|
||||
var umbracoContextFactory = new UmbracoContextFactory(
|
||||
new TestUmbracoContextAccessor(),
|
||||
Mock.Of<IPublishedSnapshotService>(),
|
||||
new TestVariationContextAccessor(),
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
TestObjects.GetGlobalSettings(),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
// just assert it does not throw
|
||||
var refreshers = new DistributedCacheBinder(null, null);
|
||||
var refreshers = new DistributedCacheBinder(null, umbracoContextFactory, null);
|
||||
refreshers.HandleEvents(definitions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,7 +473,7 @@ namespace Umbraco.Tests.IO
|
||||
scope.Dispose();
|
||||
scopedFileSystems = false;
|
||||
Assert.IsTrue(phy.FileExists("sub/f5.txt"));
|
||||
Assert.IsFalse(Directory.Exists(shadowfs + "/" + id));
|
||||
TestHelper.TryAssert(() => Assert.IsFalse(Directory.Exists(shadowfs + "/" + id)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -13,6 +13,7 @@ using Umbraco.Core.Sync;
|
||||
using Umbraco.Tests.Services;
|
||||
using Umbraco.Tests.TestHelpers.Entities;
|
||||
using Umbraco.Tests.Testing;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Cache;
|
||||
using static Umbraco.Tests.Cache.DistributedCache.DistributedCacheTests;
|
||||
|
||||
@@ -32,7 +33,7 @@ namespace Umbraco.Tests.Integration
|
||||
{
|
||||
base.SetUp();
|
||||
|
||||
_h1 = new DistributedCacheBinder(new DistributedCache(), Mock.Of<ILogger>());
|
||||
_h1 = new DistributedCacheBinder(new DistributedCache(), Mock.Of<IUmbracoContextFactory>(), Mock.Of<ILogger>());
|
||||
_h1.BindEvents(true);
|
||||
|
||||
_events = new List<EventInstance>();
|
||||
|
||||
@@ -51,10 +51,13 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
|
||||
return new ForcedPreviewObject();
|
||||
}
|
||||
|
||||
private class ForcedPreviewObject : DisposableObject
|
||||
private class ForcedPreviewObject : DisposableObjectSlim
|
||||
{
|
||||
protected override void DisposeResources()
|
||||
{ }
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
|
||||
{
|
||||
get
|
||||
{
|
||||
var umbracoContext = UmbracoContext.Current;
|
||||
var umbracoContext = Umbraco.Web.Composing.Current.UmbracoContext;
|
||||
|
||||
// will get or create a value
|
||||
// a ConditionalWeakTable is thread-safe
|
||||
|
||||
@@ -4,12 +4,12 @@ using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Tests.Testing;
|
||||
using Umbraco.Web;
|
||||
using Current = Umbraco.Web.Composing.Current;
|
||||
|
||||
namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
@@ -186,7 +186,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Can_Get_Content_For_Populated_Requested_Language()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First();
|
||||
var value = content.Value("welcomeText", "en-US");
|
||||
Assert.AreEqual("Welcome", value);
|
||||
}
|
||||
@@ -194,7 +194,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Can_Get_Content_For_Populated_Requested_Non_Default_Language()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First();
|
||||
var value = content.Value("welcomeText", "de");
|
||||
Assert.AreEqual("Willkommen", value);
|
||||
}
|
||||
@@ -202,7 +202,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Do_Not_Get_Content_For_Unpopulated_Requested_Language_Without_Fallback()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First();
|
||||
var value = content.Value("welcomeText", "fr");
|
||||
Assert.IsNull(value);
|
||||
}
|
||||
@@ -210,7 +210,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Do_Not_Get_Content_For_Unpopulated_Requested_Language_With_Fallback_Unless_Requested()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First();
|
||||
var value = content.Value("welcomeText", "es");
|
||||
Assert.IsNull(value);
|
||||
}
|
||||
@@ -218,7 +218,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Can_Get_Content_For_Unpopulated_Requested_Language_With_Fallback()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First();
|
||||
var value = content.Value("welcomeText", "es", fallback: Fallback.ToLanguage);
|
||||
Assert.AreEqual("Welcome", value);
|
||||
}
|
||||
@@ -226,7 +226,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Can_Get_Content_For_Unpopulated_Requested_Language_With_Fallback_Over_Two_Levels()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First();
|
||||
var value = content.Value("welcomeText", "it", fallback: Fallback.To(Fallback.Language, Fallback.Ancestors));
|
||||
Assert.AreEqual("Welcome", value);
|
||||
}
|
||||
@@ -234,7 +234,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Do_Not_GetContent_For_Unpopulated_Requested_Language_With_Fallback_Over_That_Loops()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First();
|
||||
var value = content.Value("welcomeText", "no", fallback: Fallback.ToLanguage);
|
||||
Assert.IsNull(value);
|
||||
}
|
||||
@@ -242,7 +242,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Do_Not_Get_Content_Recursively_Unless_Requested()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First().Children.First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First().Children.First();
|
||||
var value = content.Value("welcomeText2");
|
||||
Assert.IsNull(value);
|
||||
}
|
||||
@@ -250,7 +250,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Can_Get_Content_Recursively()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First().Children.First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First().Children.First();
|
||||
var value = content.Value("welcomeText2", fallback: Fallback.ToAncestors);
|
||||
Assert.AreEqual("Welcome", value);
|
||||
}
|
||||
@@ -258,7 +258,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Do_Not_Get_Content_Recursively_Unless_Requested2()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First().Children.First().Children().First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First().Children.First().Children().First();
|
||||
Assert.IsNull(content.GetProperty("welcomeText2"));
|
||||
var value = content.Value("welcomeText2");
|
||||
Assert.IsNull(value);
|
||||
@@ -267,7 +267,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Can_Get_Content_Recursively2()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First().Children.First().Children().First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First().Children.First().Children().First();
|
||||
Assert.IsNull(content.GetProperty("welcomeText2"));
|
||||
var value = content.Value("welcomeText2", fallback: Fallback.ToAncestors);
|
||||
Assert.AreEqual("Welcome", value);
|
||||
@@ -276,7 +276,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Can_Get_Content_Recursively3()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First().Children.First().Children().First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First().Children.First().Children().First();
|
||||
Assert.IsNull(content.GetProperty("noprop"));
|
||||
var value = content.Value("noprop", fallback: Fallback.ToAncestors);
|
||||
// property has no value but we still get the value (ie, the converter would do something)
|
||||
@@ -287,7 +287,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
public void Can_Get_Content_With_Recursive_Priority()
|
||||
{
|
||||
Current.VariationContextAccessor.VariationContext = new VariationContext("nl");
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First().Children.First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First().Children.First();
|
||||
|
||||
var value = content.Value("welcomeText", "nl", fallback: Fallback.To(Fallback.Ancestors, Fallback.Language));
|
||||
|
||||
@@ -298,7 +298,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Can_Get_Content_With_Fallback_Language_Priority()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First().Children.First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First().Children.First();
|
||||
var value = content.Value("welcomeText", "nl", fallback: Fallback.ToLanguage);
|
||||
|
||||
// No Dutch value is directly assigned. Check has fallen back to English value from language variant.
|
||||
@@ -308,14 +308,14 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Throws_For_Non_Supported_Fallback()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First().Children.First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First().Children.First();
|
||||
Assert.Throws<NotSupportedException>(() => content.Value("welcomeText", "nl", fallback: Fallback.To(999)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Fallback_To_Default_Value()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First().Children.First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First().Children.First();
|
||||
|
||||
// no Dutch value is assigned, so getting null
|
||||
var value = content.Value("welcomeText", "nl");
|
||||
@@ -333,7 +333,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Can_Have_Custom_Default_Value()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First().Children.First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First().Children.First();
|
||||
|
||||
// HACK: the value, pretend the converter would return something
|
||||
var prop = content.GetProperty("welcomeText") as SolidPublishedPropertyWithLanguageVariants;
|
||||
|
||||
@@ -5,6 +5,7 @@ using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Tests.Testing;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Tests.PublishedContent
|
||||
{
|
||||
@@ -95,14 +96,14 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void First()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First();
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot().First();
|
||||
Assert.AreEqual("Content 1", content.Name);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Distinct()
|
||||
{
|
||||
var items = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
var items = Current.UmbracoContext.ContentCache.GetAtRoot()
|
||||
.Distinct()
|
||||
.Distinct()
|
||||
.ToIndexedArray();
|
||||
@@ -126,7 +127,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void OfType1()
|
||||
{
|
||||
var items = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
var items = Current.UmbracoContext.ContentCache.GetAtRoot()
|
||||
.OfType<ContentType2>()
|
||||
.Distinct()
|
||||
.ToIndexedArray();
|
||||
@@ -137,7 +138,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void OfType2()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot()
|
||||
.OfType<ContentType2Sub>()
|
||||
.Distinct()
|
||||
.ToIndexedArray();
|
||||
@@ -148,7 +149,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void OfType()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot()
|
||||
.OfType<ContentType2>()
|
||||
.First(x => x.Prop1 == 1234);
|
||||
Assert.AreEqual("Content 2", content.Name);
|
||||
@@ -158,7 +159,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Position()
|
||||
{
|
||||
var items = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
var items = Current.UmbracoContext.ContentCache.GetAtRoot()
|
||||
.Where(x => x.Value<int>("prop1") == 1234)
|
||||
.ToIndexedArray();
|
||||
|
||||
@@ -173,7 +174,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void Issue()
|
||||
{
|
||||
var content = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
var content = Current.UmbracoContext.ContentCache.GetAtRoot()
|
||||
.Distinct()
|
||||
.OfType<ContentType2>();
|
||||
|
||||
@@ -181,12 +182,12 @@ namespace Umbraco.Tests.PublishedContent
|
||||
var first = where.First();
|
||||
Assert.AreEqual(1234, first.Prop1);
|
||||
|
||||
var content2 = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
var content2 = Current.UmbracoContext.ContentCache.GetAtRoot()
|
||||
.OfType<ContentType2>()
|
||||
.First(x => x.Prop1 == 1234);
|
||||
Assert.AreEqual(1234, content2.Prop1);
|
||||
|
||||
var content3 = UmbracoContext.Current.ContentCache.GetAtRoot()
|
||||
var content3 = Current.UmbracoContext.ContentCache.GetAtRoot()
|
||||
.OfType<ContentType2>()
|
||||
.First();
|
||||
Assert.AreEqual(1234, content3.Prop1);
|
||||
@@ -195,7 +196,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
[Test]
|
||||
public void PublishedContentQueryTypedContentList()
|
||||
{
|
||||
var query = new PublishedContentQuery(UmbracoContext.Current.PublishedSnapshot, UmbracoContext.Current.VariationContextAccessor);
|
||||
var query = new PublishedContentQuery(Current.UmbracoContext.PublishedSnapshot, Current.UmbracoContext.VariationContextAccessor);
|
||||
var result = query.Content(new[] { 1, 2, 4 }).ToArray();
|
||||
Assert.AreEqual(2, result.Length);
|
||||
Assert.AreEqual(1, result[0].Id);
|
||||
|
||||
@@ -39,6 +39,9 @@ namespace Umbraco.Tests.PublishedContent
|
||||
public IAppCache SnapshotCache => null;
|
||||
|
||||
public IAppCache ElementsCache => null;
|
||||
|
||||
public void Dispose()
|
||||
{ }
|
||||
}
|
||||
|
||||
class SolidPublishedContentCache : PublishedCacheBase, IPublishedContentCache, IPublishedMediaCache
|
||||
|
||||
@@ -45,7 +45,8 @@ namespace Umbraco.Tests.Routing
|
||||
runtime,
|
||||
logger,
|
||||
null, // FIXME: PublishedRouter complexities...
|
||||
Mock.Of<IVariationContextAccessor>()
|
||||
Mock.Of<IVariationContextAccessor>(),
|
||||
Mock.Of<IUmbracoContextFactory>()
|
||||
);
|
||||
|
||||
runtime.Level = RuntimeLevel.Run;
|
||||
|
||||
@@ -100,6 +100,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
composition.WithCollectionBuilder<UrlProviderCollectionBuilder>().Append<DefaultUrlProvider>();
|
||||
composition.RegisterUnique<IDistributedCacheBinder, DistributedCacheBinder>();
|
||||
composition.RegisterUnique<IExamineManager>(f => ExamineManager.Instance);
|
||||
composition.RegisterUnique<IUmbracoContextFactory, UmbracoContextFactory>();
|
||||
|
||||
// initialize some components only/individually
|
||||
composition.WithCollectionBuilder<ComponentCollectionBuilder>()
|
||||
@@ -178,8 +179,9 @@ namespace Umbraco.Tests.Runtimes
|
||||
// need an UmbracoCOntext to access the cache
|
||||
// FIXME: not exactly pretty, should not depend on HttpContext
|
||||
var httpContext = Mock.Of<HttpContextBase>();
|
||||
var withUmbracoContext = UmbracoContext.EnsureContext(httpContext);
|
||||
var umbracoContext = Umbraco.Web.Composing.Current.UmbracoContext;
|
||||
var umbracoContextFactory = factory.GetInstance<IUmbracoContextFactory>();
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(httpContext);
|
||||
var umbracoContext = umbracoContextReference.UmbracoContext;
|
||||
|
||||
// assert that there is no published document
|
||||
var pcontent = umbracoContext.ContentCache.GetById(content.Id);
|
||||
@@ -217,7 +219,7 @@ namespace Umbraco.Tests.Runtimes
|
||||
// and the published document has a url
|
||||
Assert.AreEqual("/test/", pcontent.GetUrl());
|
||||
|
||||
withUmbracoContext.Dispose();
|
||||
umbracoContextReference.Dispose();
|
||||
mainDom.Stop();
|
||||
components.Terminate();
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace Umbraco.Tests.Scoping
|
||||
var umbracoContext = GetUmbracoContextNu("http://example.com/", setSingleton: true);
|
||||
|
||||
// wire cache refresher
|
||||
_distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(), Mock.Of<ILogger>());
|
||||
_distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(), Mock.Of<IUmbracoContextFactory>(), Mock.Of<ILogger>());
|
||||
_distributedCacheBinder.BindEvents(true);
|
||||
|
||||
// create document type, document
|
||||
|
||||
@@ -15,6 +15,7 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Web;
|
||||
|
||||
namespace Umbraco.Tests.Scoping
|
||||
{
|
||||
@@ -74,7 +75,7 @@ namespace Umbraco.Tests.Scoping
|
||||
// get user again - else we'd modify the one that's in the cache
|
||||
user = service.GetUserById(user.Id);
|
||||
|
||||
_distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(), Mock.Of<ILogger>());
|
||||
_distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(), Mock.Of<IUmbracoContextFactory>(), Mock.Of<ILogger>());
|
||||
_distributedCacheBinder.BindEvents(true);
|
||||
|
||||
Assert.IsNull(scopeProvider.AmbientScope);
|
||||
@@ -155,7 +156,7 @@ namespace Umbraco.Tests.Scoping
|
||||
Assert.AreEqual(lang.Id, globalCached.Id);
|
||||
Assert.AreEqual("fr-FR", globalCached.IsoCode);
|
||||
|
||||
_distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(), Mock.Of<ILogger>());
|
||||
_distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(), Mock.Of<IUmbracoContextFactory>(), Mock.Of<ILogger>());
|
||||
_distributedCacheBinder.BindEvents(true);
|
||||
|
||||
Assert.IsNull(scopeProvider.AmbientScope);
|
||||
@@ -247,7 +248,7 @@ namespace Umbraco.Tests.Scoping
|
||||
Assert.AreEqual(item.Id, globalCached.Id);
|
||||
Assert.AreEqual("item-key", globalCached.ItemKey);
|
||||
|
||||
_distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(), Mock.Of<ILogger>());
|
||||
_distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(), Mock.Of<IUmbracoContextFactory>(), Mock.Of<ILogger>());
|
||||
_distributedCacheBinder.BindEvents(true);
|
||||
|
||||
Assert.IsNull(scopeProvider.AmbientScope);
|
||||
|
||||
@@ -16,6 +16,7 @@ using Umbraco.Core.Sync;
|
||||
using Umbraco.Tests.LegacyXmlPublishedCache;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.Testing;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Cache;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
|
||||
@@ -92,7 +93,7 @@ namespace Umbraco.Tests.Scoping
|
||||
var item = new Content("name", -1, contentType);
|
||||
|
||||
// wire cache refresher
|
||||
_distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(), Mock.Of<ILogger>());
|
||||
_distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(), Mock.Of<IUmbracoContextFactory>(), Mock.Of<ILogger>());
|
||||
_distributedCacheBinder.BindEvents(true);
|
||||
|
||||
// check xml in context = "before"
|
||||
@@ -205,7 +206,7 @@ namespace Umbraco.Tests.Scoping
|
||||
Current.Services.ContentTypeService.Save(contentType);
|
||||
|
||||
// wire cache refresher
|
||||
_distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(), Mock.Of<ILogger>());
|
||||
_distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(), Mock.Of<IUmbracoContextFactory>(), Mock.Of<ILogger>());
|
||||
_distributedCacheBinder.BindEvents(true);
|
||||
|
||||
// check xml in context = "before"
|
||||
|
||||
@@ -135,16 +135,16 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting
|
||||
|
||||
var umbracoContextAccessor = Umbraco.Web.Composing.Current.UmbracoContextAccessor;
|
||||
|
||||
var umbCtx = UmbracoContext.EnsureContext(
|
||||
umbracoContextAccessor,
|
||||
httpContext,
|
||||
var umbCtx = new UmbracoContext(httpContext,
|
||||
publishedSnapshotService.Object,
|
||||
webSecurity.Object,
|
||||
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == Mock.Of<IWebRoutingSection>(routingSection => routingSection.UrlProviderMode == UrlProviderMode.Auto.ToString())),
|
||||
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == Mock.Of<IWebRoutingSection>(routingSection => routingSection.UrlProviderMode == "Auto")),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
globalSettings,
|
||||
new TestVariationContextAccessor(),
|
||||
true); //replace it
|
||||
new TestVariationContextAccessor());
|
||||
|
||||
//replace it
|
||||
umbracoContextAccessor.UmbracoContext = umbCtx;
|
||||
|
||||
var urlHelper = new Mock<IUrlProvider>();
|
||||
urlHelper.Setup(provider => provider.GetUrl(It.IsAny<UmbracoContext>(), It.IsAny<IPublishedContent>(), It.IsAny<UrlProviderMode>(), It.IsAny<string>(), It.IsAny<Uri>()))
|
||||
|
||||
@@ -116,11 +116,21 @@ namespace Umbraco.Tests.TestHelpers
|
||||
|
||||
var umbracoSettings = GetUmbracoSettings();
|
||||
var globalSettings = GetGlobalSettings();
|
||||
var webSecurity = new Mock<WebSecurity>(null, null, globalSettings).Object;
|
||||
var urlProviders = Enumerable.Empty<IUrlProvider>();
|
||||
|
||||
if (accessor == null) accessor = new TestUmbracoContextAccessor();
|
||||
return UmbracoContext.EnsureContext(accessor, httpContext, publishedSnapshotService, webSecurity, umbracoSettings, urlProviders, globalSettings, new TestVariationContextAccessor(), true);
|
||||
|
||||
var umbracoContextFactory = new UmbracoContextFactory(
|
||||
accessor,
|
||||
publishedSnapshotService,
|
||||
new TestVariationContextAccessor(),
|
||||
new TestDefaultCultureAccessor(),
|
||||
umbracoSettings,
|
||||
globalSettings,
|
||||
urlProviders,
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
return umbracoContextFactory.EnsureUmbracoContext(httpContext).UmbracoContext;
|
||||
}
|
||||
|
||||
public IUmbracoSettingsSection GetUmbracoSettings()
|
||||
@@ -143,7 +153,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
public IFileSystems GetFileSystemsMock()
|
||||
{
|
||||
var fileSystems = Mock.Of<IFileSystems>();
|
||||
|
||||
|
||||
MockFs(fileSystems, x => x.MacroPartialsFileSystem);
|
||||
MockFs(fileSystems, x => x.MvcViewsFileSystem);
|
||||
MockFs(fileSystems, x => x.PartialViewsFileSystem);
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Umbraco.Tests.Testing.TestingTests
|
||||
public void Can_Mock_Umbraco_Context()
|
||||
{
|
||||
var umbracoContext = TestObjects.GetUmbracoContextMock(Current.UmbracoContextAccessor);
|
||||
Assert.AreEqual(umbracoContext, UmbracoContext.Current);
|
||||
Assert.AreEqual(umbracoContext, Current.UmbracoContext);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -63,19 +63,20 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
var globalSettings = TestObjects.GetGlobalSettings();
|
||||
var attr = new RenderIndexActionSelectorAttribute();
|
||||
var req = new RequestContext();
|
||||
//var appCtx = new ApplicationContext(
|
||||
// CacheHelper.CreateDisabledCacheHelper(),
|
||||
// new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
|
||||
var umbCtx = UmbracoContext.EnsureContext(
|
||||
|
||||
var umbracoContextFactory = new UmbracoContextFactory(
|
||||
Current.UmbracoContextAccessor,
|
||||
Mock.Of<HttpContextBase>(),
|
||||
Mock.Of<IPublishedSnapshotService>(),
|
||||
new Mock<WebSecurity>(null, null, globalSettings).Object,
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
globalSettings,
|
||||
new TestVariationContextAccessor(),
|
||||
true);
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
var umbCtx = umbracoContextReference.UmbracoContext;
|
||||
|
||||
var ctrl = new MatchesDefaultIndexController { UmbracoContext = umbCtx };
|
||||
var controllerCtx = new ControllerContext(req, ctrl);
|
||||
var result = attr.IsValidForRequest(controllerCtx,
|
||||
@@ -90,16 +91,20 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
var globalSettings = TestObjects.GetGlobalSettings();
|
||||
var attr = new RenderIndexActionSelectorAttribute();
|
||||
var req = new RequestContext();
|
||||
var umbCtx = UmbracoContext.EnsureContext(
|
||||
|
||||
var umbracoContextFactory = new UmbracoContextFactory(
|
||||
Current.UmbracoContextAccessor,
|
||||
Mock.Of<HttpContextBase>(),
|
||||
Mock.Of<IPublishedSnapshotService>(),
|
||||
new Mock<WebSecurity>(null, null, globalSettings).Object,
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
globalSettings,
|
||||
new TestVariationContextAccessor(),
|
||||
true);
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
var umbCtx = umbracoContextReference.UmbracoContext;
|
||||
|
||||
var ctrl = new MatchesOverriddenIndexController { UmbracoContext = umbCtx };
|
||||
var controllerCtx = new ControllerContext(req, ctrl);
|
||||
var result = attr.IsValidForRequest(controllerCtx,
|
||||
@@ -114,16 +119,20 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
var globalSettings = TestObjects.GetGlobalSettings();
|
||||
var attr = new RenderIndexActionSelectorAttribute();
|
||||
var req = new RequestContext();
|
||||
var umbCtx = UmbracoContext.EnsureContext(
|
||||
|
||||
var umbracoContextFactory = new UmbracoContextFactory(
|
||||
Current.UmbracoContextAccessor,
|
||||
Mock.Of<HttpContextBase>(),
|
||||
Mock.Of<IPublishedSnapshotService>(),
|
||||
new Mock<WebSecurity>(null, null, globalSettings).Object,
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
globalSettings,
|
||||
new TestVariationContextAccessor(),
|
||||
true);
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
var umbCtx = umbracoContextReference.UmbracoContext;
|
||||
|
||||
var ctrl = new MatchesCustomIndexController { UmbracoContext = umbCtx };
|
||||
var controllerCtx = new ControllerContext(req, ctrl);
|
||||
var result = attr.IsValidForRequest(controllerCtx,
|
||||
@@ -138,16 +147,20 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
var globalSettings = TestObjects.GetGlobalSettings();
|
||||
var attr = new RenderIndexActionSelectorAttribute();
|
||||
var req = new RequestContext();
|
||||
var umbCtx = UmbracoContext.EnsureContext(
|
||||
|
||||
var umbracoContextFactory = new UmbracoContextFactory(
|
||||
Current.UmbracoContextAccessor,
|
||||
Mock.Of<HttpContextBase>(),
|
||||
Mock.Of<IPublishedSnapshotService>(),
|
||||
new Mock<WebSecurity>(null, null, globalSettings).Object,
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
globalSettings,
|
||||
new TestVariationContextAccessor(),
|
||||
true);
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
var umbCtx = umbracoContextReference.UmbracoContext;
|
||||
|
||||
var ctrl = new MatchesAsyncIndexController { UmbracoContext = umbCtx };
|
||||
var controllerCtx = new ControllerContext(req, ctrl);
|
||||
var result = attr.IsValidForRequest(controllerCtx,
|
||||
|
||||
@@ -40,16 +40,19 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
public void Can_Construct_And_Get_Result()
|
||||
{
|
||||
var globalSettings = TestObjects.GetGlobalSettings();
|
||||
var umbracoContext = UmbracoContext.EnsureContext(
|
||||
|
||||
var umbracoContextFactory = new UmbracoContextFactory(
|
||||
Current.UmbracoContextAccessor,
|
||||
new Mock<HttpContextBase>().Object,
|
||||
Mock.Of<IPublishedSnapshotService>(),
|
||||
new Mock<WebSecurity>(null, null, globalSettings).Object,
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
globalSettings,
|
||||
new TestVariationContextAccessor(),
|
||||
true);
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
var umbracoContext = umbracoContextReference.UmbracoContext;
|
||||
|
||||
var ctrl = new TestSurfaceController(umbracoContext);
|
||||
|
||||
@@ -62,22 +65,25 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
public void Umbraco_Context_Not_Null()
|
||||
{
|
||||
var globalSettings = TestObjects.GetGlobalSettings();
|
||||
var umbCtx = UmbracoContext.EnsureContext(
|
||||
|
||||
var umbracoContextFactory = new UmbracoContextFactory(
|
||||
Current.UmbracoContextAccessor,
|
||||
new Mock<HttpContextBase>().Object,
|
||||
Mock.Of<IPublishedSnapshotService>(),
|
||||
new Mock<WebSecurity>(null, null, globalSettings).Object,
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
globalSettings,
|
||||
new TestVariationContextAccessor(),
|
||||
true);
|
||||
new TestDefaultCultureAccessor(),
|
||||
TestObjects.GetUmbracoSettings(),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
var umbCtx = umbracoContextReference.UmbracoContext;
|
||||
|
||||
var ctrl = new TestSurfaceController(umbCtx);
|
||||
|
||||
Assert.IsNotNull(ctrl.UmbracoContext);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Can_Lookup_Content()
|
||||
{
|
||||
@@ -88,16 +94,18 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
var publishedSnapshotService = new Mock<IPublishedSnapshotService>();
|
||||
var globalSettings = TestObjects.GetGlobalSettings();
|
||||
|
||||
var umbracoContext = UmbracoContext.EnsureContext(
|
||||
var umbracoContextFactory = new UmbracoContextFactory(
|
||||
Current.UmbracoContextAccessor,
|
||||
new Mock<HttpContextBase>().Object,
|
||||
publishedSnapshotService.Object,
|
||||
new Mock<WebSecurity>(null, null, globalSettings).Object,
|
||||
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == Mock.Of<IWebRoutingSection>(routingSection => routingSection.UrlProviderMode == "Auto")),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
globalSettings,
|
||||
new TestVariationContextAccessor(),
|
||||
true);
|
||||
new TestDefaultCultureAccessor(),
|
||||
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == Mock.Of<IWebRoutingSection>(routingSection => routingSection.UrlProviderMode == "Auto")),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
var umbracoContext = umbracoContextReference.UmbracoContext;
|
||||
|
||||
var helper = new UmbracoHelper(
|
||||
umbracoContext,
|
||||
@@ -121,16 +129,18 @@ namespace Umbraco.Tests.Web.Mvc
|
||||
var webRoutingSettings = Mock.Of<IWebRoutingSection>(section => section.UrlProviderMode == "Auto");
|
||||
var globalSettings = TestObjects.GetGlobalSettings();
|
||||
|
||||
var umbracoContext = UmbracoContext.EnsureContext(
|
||||
var umbracoContextFactory = new UmbracoContextFactory(
|
||||
Current.UmbracoContextAccessor,
|
||||
new Mock<HttpContextBase>().Object,
|
||||
Mock.Of<IPublishedSnapshotService>(),
|
||||
new Mock<WebSecurity>(null, null, globalSettings).Object,
|
||||
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == webRoutingSettings),
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
globalSettings,
|
||||
new TestVariationContextAccessor(),
|
||||
true);
|
||||
new TestDefaultCultureAccessor(),
|
||||
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == webRoutingSettings),
|
||||
globalSettings,
|
||||
Enumerable.Empty<IUrlProvider>(),
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
var umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>());
|
||||
var umbracoContext = umbracoContextReference.UmbracoContext;
|
||||
|
||||
var content = Mock.Of<IPublishedContent>(publishedContent => publishedContent.Id == 12345);
|
||||
|
||||
|
||||
@@ -96,20 +96,19 @@ namespace Umbraco.Tests.Web
|
||||
var snapshotService = Mock.Of<IPublishedSnapshotService>();
|
||||
Mock.Get(snapshotService).Setup(x => x.CreatePublishedSnapshot(It.IsAny<string>())).Returns(snapshot);
|
||||
|
||||
using (var umbCtx = UmbracoContext.EnsureContext(
|
||||
var umbracoContextFactory = new UmbracoContextFactory(
|
||||
Umbraco.Web.Composing.Current.UmbracoContextAccessor,
|
||||
Mock.Of<HttpContextBase>(),
|
||||
snapshotService,
|
||||
new Mock<WebSecurity>(null, null, globalSettings).Object,
|
||||
//setup a quick mock of the WebRouting section
|
||||
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == Mock.Of<IWebRoutingSection>(routingSection => routingSection.UrlProviderMode == "Auto")),
|
||||
//pass in the custom url provider
|
||||
new[]{ testUrlProvider.Object },
|
||||
globalSettings,
|
||||
new TestVariationContextAccessor(),
|
||||
true))
|
||||
new TestDefaultCultureAccessor(),
|
||||
Mock.Of<IUmbracoSettingsSection>(section => section.WebRouting == Mock.Of<IWebRoutingSection>(routingSection => routingSection.UrlProviderMode == "Auto")),
|
||||
globalSettings,
|
||||
new[] { testUrlProvider.Object },
|
||||
Mock.Of<IUserService>());
|
||||
|
||||
using (var reference = umbracoContextFactory.EnsureUmbracoContext(Mock.Of<HttpContextBase>()))
|
||||
{
|
||||
var output = TemplateUtilities.ParseInternalLinks(input, umbCtx.UrlProvider);
|
||||
var output = TemplateUtilities.ParseInternalLinks(input, reference.UmbracoContext.UrlProvider);
|
||||
|
||||
Assert.AreEqual(result, output);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.WebPages;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Web.UI.Config.Splashes
|
||||
{
|
||||
@@ -13,7 +14,7 @@ namespace Umbraco.Web.UI.Config.Splashes
|
||||
{
|
||||
base.OnInit(e);
|
||||
|
||||
var store = UmbracoContext.Current.ContentCache;
|
||||
var store = Current.UmbracoContext.ContentCache;
|
||||
if (store.HasContent())
|
||||
{
|
||||
//if there is actually content, go to the root
|
||||
|
||||
@@ -12,6 +12,7 @@ using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
@@ -102,7 +103,7 @@ namespace Umbraco.Web
|
||||
// try get the http context from the UmbracoContext, we do this because in the case we are launching an async
|
||||
// thread and we know that the cache refreshers will execute, we will ensure the UmbracoContext and therefore we
|
||||
// can get the http context from it
|
||||
var httpContext = (UmbracoContext.Current == null ? null : UmbracoContext.Current.HttpContext)
|
||||
var httpContext = (Current.UmbracoContext == null ? null : Current.UmbracoContext.HttpContext)
|
||||
// if this is null, it could be that an async thread is calling this method that we weren't aware of and the UmbracoContext
|
||||
// wasn't ensured at the beginning of the thread. We can try to see if the HttpContext.Current is available which might be
|
||||
// the case if the asp.net synchronization context has kicked in
|
||||
|
||||
@@ -16,17 +16,17 @@ namespace Umbraco.Web.Cache
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, MethodInfo> FoundHandlers = new ConcurrentDictionary<string, MethodInfo>();
|
||||
private readonly DistributedCache _distributedCache;
|
||||
private readonly IUmbracoContextFactory _umbracoContextFactory;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DistributedCacheBinder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="distributedCache"></param>
|
||||
/// <param name="logger"></param>
|
||||
public DistributedCacheBinder(DistributedCache distributedCache, ILogger logger)
|
||||
public DistributedCacheBinder(DistributedCache distributedCache, IUmbracoContextFactory umbracoContextFactory, ILogger logger)
|
||||
{
|
||||
_distributedCache = distributedCache;
|
||||
_logger = logger;
|
||||
_umbracoContextFactory = umbracoContextFactory;
|
||||
}
|
||||
|
||||
// internal for tests
|
||||
@@ -64,7 +64,7 @@ namespace Umbraco.Web.Cache
|
||||
{
|
||||
// ensure we run with an UmbracoContext, because this may run in a background task,
|
||||
// yet developers may be using the 'current' UmbracoContext in the event handlers
|
||||
using (UmbracoContext.EnsureContext())
|
||||
using (_umbracoContextFactory.EnsureUmbracoContext())
|
||||
{
|
||||
foreach (var e in events)
|
||||
{
|
||||
|
||||
@@ -44,7 +44,10 @@ namespace Umbraco.Web.Composing
|
||||
CoreCurrent.Resetted += (sender, args) =>
|
||||
{
|
||||
if (_umbracoContextAccessor != null)
|
||||
ClearUmbracoContext();
|
||||
{
|
||||
var umbracoContext = _umbracoContextAccessor.UmbracoContext;
|
||||
umbracoContext?.Dispose();
|
||||
}
|
||||
_umbracoContextAccessor = null;
|
||||
};
|
||||
}
|
||||
@@ -75,18 +78,6 @@ namespace Umbraco.Web.Composing
|
||||
set => _umbracoContextAccessor = value; // for tests
|
||||
}
|
||||
|
||||
// clears the "current" umbraco context
|
||||
// at the moment the "current" umbraco context can end up being disposed and should get cleared
|
||||
// in the accessor - this should be done differently but for the time being we have to support it
|
||||
public static void ClearUmbracoContext()
|
||||
{
|
||||
lock (Locker)
|
||||
{
|
||||
UmbracoContextAccessor.UmbracoContext?.Dispose(); // dispose the one that is being cleared, if any
|
||||
UmbracoContextAccessor.UmbracoContext = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Web Getters
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Web.Http.Filters;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.Editors.Filters
|
||||
@@ -14,7 +15,7 @@ namespace Umbraco.Web.Editors.Filters
|
||||
{
|
||||
if (actionExecutedContext.Response == null) return;
|
||||
|
||||
var user = UmbracoContext.Current.Security.CurrentUser;
|
||||
var user = Current.UmbracoContext.Security.CurrentUser;
|
||||
if (user == null) return;
|
||||
|
||||
var objectContent = actionExecutedContext.Response.Content as ObjectContent;
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Umbraco.Web.Editors.Filters
|
||||
|
||||
private UmbracoContext GetUmbracoContext()
|
||||
{
|
||||
return _umbracoContext ?? UmbracoContext.Current;
|
||||
return _umbracoContext ?? Composing.Current.UmbracoContext;
|
||||
}
|
||||
|
||||
protected override bool IsAuthorized(HttpActionContext actionContext)
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
}
|
||||
//Get all allowed sections for the current user
|
||||
var allowedSections = UmbracoContext.Current.Security.CurrentUser.AllowedSections.ToList();
|
||||
var allowedSections = Composing.Current.UmbracoContext.Security.CurrentUser.AllowedSections.ToList();
|
||||
|
||||
var toursToBeRemoved = new List<BackOfficeTourFile>();
|
||||
|
||||
|
||||
@@ -63,12 +63,12 @@ namespace Umbraco.Web
|
||||
/// </remarks>
|
||||
public static MvcHtmlString PreviewBadge(this HtmlHelper helper)
|
||||
{
|
||||
if (UmbracoContext.Current.InPreviewMode)
|
||||
if (Current.UmbracoContext.InPreviewMode)
|
||||
{
|
||||
var htmlBadge =
|
||||
String.Format(Current.Configs.Settings().Content.PreviewBadge,
|
||||
IOHelper.ResolveUrl(SystemDirectories.Umbraco),
|
||||
UmbracoContext.Current.HttpContext.Server.UrlEncode(UmbracoContext.Current.HttpContext.Request.Path));
|
||||
Current.UmbracoContext.HttpContext.Server.UrlEncode(Current.UmbracoContext.HttpContext.Request.Path));
|
||||
return new MvcHtmlString(htmlBadge);
|
||||
}
|
||||
return new MvcHtmlString("");
|
||||
@@ -88,11 +88,11 @@ namespace Umbraco.Web
|
||||
var cacheKey = new StringBuilder(partialViewName);
|
||||
if (cacheByPage)
|
||||
{
|
||||
if (UmbracoContext.Current == null)
|
||||
if (Current.UmbracoContext == null)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot cache by page if the UmbracoContext has not been initialized, this parameter can only be used in the context of an Umbraco request");
|
||||
}
|
||||
cacheKey.AppendFormat("{0}-", UmbracoContext.Current.PublishedRequest?.PublishedContent?.Id ?? 0);
|
||||
cacheKey.AppendFormat("{0}-", Current.UmbracoContext.PublishedRequest?.PublishedContent?.Id ?? 0);
|
||||
}
|
||||
if (cacheByMember)
|
||||
{
|
||||
@@ -690,7 +690,7 @@ namespace Umbraco.Web
|
||||
if (string.IsNullOrEmpty(action)) throw new ArgumentNullOrEmptyException(nameof(action));
|
||||
if (string.IsNullOrEmpty(controllerName)) throw new ArgumentNullOrEmptyException(nameof(controllerName));
|
||||
|
||||
var formAction = UmbracoContext.Current.OriginalRequestUrl.PathAndQuery;
|
||||
var formAction = Current.UmbracoContext.OriginalRequestUrl.PathAndQuery;
|
||||
return html.RenderForm(formAction, method, htmlAttributes, controllerName, action, area, additionalRouteVals);
|
||||
}
|
||||
|
||||
|
||||
32
src/Umbraco.Web/IUmbracoContextFactory.cs
Normal file
32
src/Umbraco.Web/IUmbracoContextFactory.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates and manages <see cref="UmbracoContext"/> instances.
|
||||
/// </summary>
|
||||
public interface IUmbracoContextFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Ensures that a current <see cref="UmbracoContext"/> exists.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>If an <see cref="UmbracoContext"/> is already registered in the
|
||||
/// <see cref="IUmbracoContextAccessor"/>, returns a non-root reference to it.
|
||||
/// Otherwise, create a new instance, registers it, and return a root reference
|
||||
/// to it.</para>
|
||||
/// <para>If <paramref name="httpContext"/> is null, the factory tries to use
|
||||
/// <see cref="HttpContext.Current"/> if it exists. Otherwise, it uses a dummy
|
||||
/// <see cref="HttpContextBase"/>.</para>
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// using (var contextReference = contextFactory.EnsureUmbracoContext())
|
||||
/// {
|
||||
/// var umbracoContext = contextReference.UmbracoContext;
|
||||
/// // use umbracoContext...
|
||||
/// }
|
||||
/// </example>
|
||||
/// <param name="httpContext">An optional http context.</param>
|
||||
UmbracoContextReference EnsureUmbracoContext(HttpContextBase httpContext = null);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using System.Web.WebPages;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Web.Macros
|
||||
{
|
||||
@@ -28,9 +29,9 @@ namespace Umbraco.Web.Macros
|
||||
|
||||
_getUmbracoContext = () =>
|
||||
{
|
||||
if (UmbracoContext.Current == null)
|
||||
if (Current.UmbracoContext == null)
|
||||
throw new InvalidOperationException($"The {GetType()} cannot execute with a null UmbracoContext.Current reference.");
|
||||
return UmbracoContext.Current;
|
||||
return Current.UmbracoContext;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
@@ -23,7 +24,7 @@ namespace Umbraco.Web.Models.Mapping
|
||||
public IEnumerable<string> Resolve(IContent source)
|
||||
{
|
||||
//cannot check permissions without a context
|
||||
if (UmbracoContext.Current == null)
|
||||
if (Current.UmbracoContext == null)
|
||||
return Enumerable.Empty<string>();
|
||||
|
||||
string path;
|
||||
@@ -38,7 +39,7 @@ namespace Umbraco.Web.Models.Mapping
|
||||
// TODO: This is certainly not ideal usage here - perhaps the best way to deal with this in the future is
|
||||
// with the IUmbracoContextAccessor. In the meantime, if used outside of a web app this will throw a null
|
||||
// reference exception :(
|
||||
return UserService.GetPermissionsForPath(UmbracoContext.Current.Security.CurrentUser, path).GetAllPermissions();
|
||||
return UserService.GetPermissionsForPath(Current.UmbracoContext.Security.CurrentUser, path).GetAllPermissions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using AutoMapper;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
@@ -27,8 +28,8 @@ namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
// TODO: We can resolve the UmbracoContext from the IValueResolver options!
|
||||
// OMG
|
||||
if (HttpContext.Current != null && UmbracoContext.Current != null && UmbracoContext.Current.Security.CurrentUser != null
|
||||
&& UmbracoContext.Current.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings)))
|
||||
if (HttpContext.Current != null && Current.UmbracoContext != null && Current.UmbracoContext.Security.CurrentUser != null
|
||||
&& Current.UmbracoContext.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings)))
|
||||
{
|
||||
var contentType = _contentTypeBaseServiceProvider.GetContentTypeOf(source);
|
||||
var contentTypeBasic = Mapper.Map<IContentTypeComposition, ContentTypeBasic>(contentType);
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// <summary>
|
||||
/// Exposes the UmbracoContext
|
||||
/// </summary>
|
||||
protected UmbracoContext UmbracoContext => _umbracoContext ?? (_umbracoContext = UmbracoContext.Current);
|
||||
protected UmbracoContext UmbracoContext => _umbracoContext ?? (_umbracoContext = Current.UmbracoContext);
|
||||
|
||||
// TODO: try lazy property injection?
|
||||
private IPublishedRouter PublishedRouter => Core.Composing.Current.Factory.GetInstance<IPublishedRouter>();
|
||||
@@ -84,13 +84,13 @@ namespace Umbraco.Web.Mvc
|
||||
base.OnActionExecuted(filterContext);
|
||||
|
||||
// First we need to check if the published content request has been set, if it has we're going to ignore this and not actually do anything
|
||||
if (UmbracoContext.Current.PublishedRequest != null)
|
||||
if (Current.UmbracoContext.PublishedRequest != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UmbracoContext.Current.PublishedRequest = PublishedRouter.CreateRequest(UmbracoContext.Current);
|
||||
ConfigurePublishedContentRequest(UmbracoContext.Current.PublishedRequest, filterContext);
|
||||
Current.UmbracoContext.PublishedRequest = PublishedRouter.CreateRequest(Current.UmbracoContext);
|
||||
ConfigurePublishedContentRequest(Current.UmbracoContext.PublishedRequest, filterContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Web.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
@@ -55,7 +56,7 @@ namespace Umbraco.Web.Mvc
|
||||
if (_publishedContent != null) return _publishedContent;
|
||||
|
||||
//need to get the URL for the page
|
||||
_publishedContent = UmbracoContext.Current.ContentCache.GetById(_pageId);
|
||||
_publishedContent = Current.UmbracoContext.ContentCache.GetById(_pageId);
|
||||
|
||||
return _publishedContent;
|
||||
}
|
||||
@@ -66,7 +67,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// </summary>
|
||||
/// <param name="pageId"></param>
|
||||
public RedirectToUmbracoPageResult(int pageId)
|
||||
: this(pageId, UmbracoContext.Current)
|
||||
: this(pageId, Current.UmbracoContext)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -76,7 +77,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// <param name="pageId"></param>
|
||||
/// <param name="queryStringValues"></param>
|
||||
public RedirectToUmbracoPageResult(int pageId, NameValueCollection queryStringValues)
|
||||
: this(pageId, queryStringValues, UmbracoContext.Current)
|
||||
: this(pageId, queryStringValues, Current.UmbracoContext)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -86,7 +87,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// <param name="pageId"></param>
|
||||
/// <param name="queryString"></param>
|
||||
public RedirectToUmbracoPageResult(int pageId, string queryString)
|
||||
: this(pageId, queryString, UmbracoContext.Current)
|
||||
: this(pageId, queryString, Current.UmbracoContext)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -95,7 +96,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// </summary>
|
||||
/// <param name="publishedContent"></param>
|
||||
public RedirectToUmbracoPageResult(IPublishedContent publishedContent)
|
||||
: this(publishedContent, UmbracoContext.Current)
|
||||
: this(publishedContent, Current.UmbracoContext)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -105,7 +106,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// <param name="publishedContent"></param>
|
||||
/// <param name="queryStringValues"></param>
|
||||
public RedirectToUmbracoPageResult(IPublishedContent publishedContent, NameValueCollection queryStringValues)
|
||||
: this(publishedContent, queryStringValues, UmbracoContext.Current)
|
||||
: this(publishedContent, queryStringValues, Current.UmbracoContext)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -115,7 +116,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// <param name="queryString"></param>
|
||||
/// <param name="queryStringValues"></param>
|
||||
public RedirectToUmbracoPageResult(IPublishedContent publishedContent, string queryString)
|
||||
: this(publishedContent, queryString, UmbracoContext.Current)
|
||||
: this(publishedContent, queryString, Current.UmbracoContext)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ namespace Umbraco.Web.Mvc
|
||||
// filter / add preview banner
|
||||
if (Response.ContentType.InvariantEquals("text/html")) // ASP.NET default value
|
||||
{
|
||||
if (UmbracoContext.Current.IsDebug || UmbracoContext.Current.InPreviewMode)
|
||||
if (Current.UmbracoContext.IsDebug || Current.UmbracoContext.InPreviewMode)
|
||||
{
|
||||
var text = value.ToString();
|
||||
var pos = text.IndexOf("</body>", StringComparison.InvariantCultureIgnoreCase);
|
||||
@@ -215,13 +215,13 @@ namespace Umbraco.Web.Mvc
|
||||
{
|
||||
string markupToInject;
|
||||
|
||||
if (UmbracoContext.Current.InPreviewMode)
|
||||
if (Current.UmbracoContext.InPreviewMode)
|
||||
{
|
||||
// creating previewBadge markup
|
||||
markupToInject =
|
||||
string.Format(Current.Configs.Settings().Content.PreviewBadge,
|
||||
IOHelper.ResolveUrl(SystemDirectories.Umbraco),
|
||||
Server.UrlEncode(UmbracoContext.Current.HttpContext.Request.Url?.PathAndQuery));
|
||||
Server.UrlEncode(Current.UmbracoContext.HttpContext.Request.Url?.PathAndQuery));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// </remarks>
|
||||
protected virtual UmbracoContext GetUmbracoContext(RequestContext requestContext)
|
||||
{
|
||||
return UmbracoContext.Current;
|
||||
return Composing.Current.UmbracoContext;
|
||||
}
|
||||
|
||||
public IHttpHandler GetHttpHandler(RequestContext requestContext)
|
||||
|
||||
@@ -4,6 +4,7 @@ using HeyRed.MarkdownSharp;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Templates;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
@@ -26,7 +27,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
var sourceString = source.ToString();
|
||||
|
||||
// ensures string is parsed for {localLink} and urls are resolved correctly
|
||||
sourceString = TemplateUtilities.ParseInternalLinks(sourceString, preview, UmbracoContext.Current);
|
||||
sourceString = TemplateUtilities.ParseInternalLinks(sourceString, preview, Current.UmbracoContext);
|
||||
sourceString = TemplateUtilities.ResolveUrlsFromTextString(sourceString);
|
||||
|
||||
return sourceString;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web.Security;
|
||||
|
||||
@@ -44,7 +45,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
if (source == null)
|
||||
return null;
|
||||
|
||||
if (UmbracoContext.Current != null)
|
||||
if (Current.UmbracoContext != null)
|
||||
{
|
||||
IPublishedContent member;
|
||||
if (source is int id)
|
||||
|
||||
@@ -9,6 +9,7 @@ using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
@@ -67,7 +68,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
}
|
||||
|
||||
// TODO: Inject an UmbracoHelper and create a GetUmbracoHelper method based on either injected or singleton
|
||||
if (UmbracoContext.Current != null)
|
||||
if (Current.UmbracoContext != null)
|
||||
{
|
||||
if (propertyType.EditorAlias.Equals(Constants.PropertyEditors.Aliases.MultiNodeTreePicker))
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@ using System.Linq;
|
||||
using HtmlAgilityPack;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Macros;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
@@ -72,7 +73,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
var sourceString = source.ToString();
|
||||
|
||||
// ensures string is parsed for {localLink} and urls are resolved correctly
|
||||
sourceString = TemplateUtilities.ParseInternalLinks(sourceString, preview, UmbracoContext.Current);
|
||||
sourceString = TemplateUtilities.ParseInternalLinks(sourceString, preview, Current.UmbracoContext);
|
||||
sourceString = TemplateUtilities.ResolveUrlsFromTextString(sourceString);
|
||||
|
||||
// ensure string is parsed for macros and macros are executed correctly
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Templates;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
@@ -31,7 +32,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
var sourceString = source.ToString();
|
||||
|
||||
// ensures string is parsed for {localLink} and urls are resolved correctly
|
||||
sourceString = TemplateUtilities.ParseInternalLinks(sourceString, preview, UmbracoContext.Current);
|
||||
sourceString = TemplateUtilities.ParseInternalLinks(sourceString, preview, Current.UmbracoContext);
|
||||
sourceString = TemplateUtilities.ResolveUrlsFromTextString(sourceString);
|
||||
|
||||
return sourceString;
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Umbraco.Web.PublishedCache
|
||||
/// </summary>
|
||||
/// <remarks>A published snapshot is a point-in-time capture of the current state of
|
||||
/// everything that is "published".</remarks>
|
||||
public interface IPublishedSnapshot
|
||||
public interface IPublishedSnapshot : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IPublishedContentCache"/>.
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return new ForcedPreviewObject(this, preview, callback);
|
||||
}
|
||||
|
||||
private class ForcedPreviewObject : DisposableObject
|
||||
private class ForcedPreviewObject : DisposableObjectSlim
|
||||
{
|
||||
private readonly PublishedSnapshot _publishedSnapshot;
|
||||
private readonly bool _origPreview;
|
||||
|
||||
@@ -46,11 +46,11 @@ namespace Umbraco.Web
|
||||
switch (content.ItemType)
|
||||
{
|
||||
case PublishedItemType.Content:
|
||||
if (UmbracoContext.Current == null)
|
||||
throw new InvalidOperationException("Cannot resolve a Url for a content item when UmbracoContext.Current is null.");
|
||||
if (UmbracoContext.Current.UrlProvider == null)
|
||||
throw new InvalidOperationException("Cannot resolve a Url for a content item when UmbracoContext.Current.UrlProvider is null.");
|
||||
return UmbracoContext.Current.UrlProvider.GetUrl(content.Id, true);
|
||||
if (Current.UmbracoContext == null)
|
||||
throw new InvalidOperationException("Cannot resolve a Url for a content item when Current.UmbracoContext is null.");
|
||||
if (Current.UmbracoContext.UrlProvider == null)
|
||||
throw new InvalidOperationException("Cannot resolve a Url for a content item when Current.UmbracoContext.UrlProvider is null.");
|
||||
return Current.UmbracoContext.UrlProvider.GetUrl(content.Id, true);
|
||||
case PublishedItemType.Media:
|
||||
throw new NotSupportedException("AbsoluteUrl is not supported for media types.");
|
||||
default:
|
||||
@@ -267,7 +267,7 @@ namespace Umbraco.Web
|
||||
.And()
|
||||
.ManagedQuery(term);
|
||||
|
||||
return query.Execute().ToPublishedSearchResults(UmbracoContext.Current.ContentCache);
|
||||
return query.Execute().ToPublishedSearchResults(Current.UmbracoContext.ContentCache);
|
||||
}
|
||||
|
||||
public static IEnumerable<PublishedSearchResult> SearchChildren(this IPublishedContent content, string term, string indexName = null)
|
||||
@@ -288,7 +288,7 @@ namespace Umbraco.Web
|
||||
.And()
|
||||
.ManagedQuery(term);
|
||||
|
||||
return query.Execute().ToPublishedSearchResults(UmbracoContext.Current.ContentCache);
|
||||
return query.Execute().ToPublishedSearchResults(Current.UmbracoContext.ContentCache);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Web;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
@@ -28,7 +29,7 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
response.Clear();
|
||||
|
||||
var frequest = UmbracoContext.Current.PublishedRequest;
|
||||
var frequest = Current.UmbracoContext.PublishedRequest;
|
||||
var reason = "Cannot render the page at url '{0}'.";
|
||||
if (frequest.HasPublishedContent == false)
|
||||
reason = "No umbraco document matches the url '{0}'.";
|
||||
@@ -37,7 +38,7 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
response.Write("<html><body><h1>Page not found</h1>");
|
||||
response.Write("<h3>");
|
||||
response.Write(string.Format(reason, HttpUtility.HtmlEncode(UmbracoContext.Current.OriginalRequestUrl.PathAndQuery)));
|
||||
response.Write(string.Format(reason, HttpUtility.HtmlEncode(Current.UmbracoContext.OriginalRequestUrl.PathAndQuery)));
|
||||
response.Write("</h3>");
|
||||
if (string.IsNullOrWhiteSpace(_message) == false)
|
||||
response.Write("<p>" + _message + "</p>");
|
||||
|
||||
@@ -38,9 +38,9 @@ namespace Umbraco.Web.Routing
|
||||
{
|
||||
get
|
||||
{
|
||||
var oldRoutes = (Dictionary<ContentIdAndCulture, ContentKeyAndOldRoute>) UmbracoContext.Current.HttpContext.Items[ContextKey3];
|
||||
var oldRoutes = (Dictionary<ContentIdAndCulture, ContentKeyAndOldRoute>) Current.UmbracoContext.HttpContext.Items[ContextKey3];
|
||||
if (oldRoutes == null)
|
||||
UmbracoContext.Current.HttpContext.Items[ContextKey3] = oldRoutes = new Dictionary<ContentIdAndCulture, ContentKeyAndOldRoute>();
|
||||
Current.UmbracoContext.HttpContext.Items[ContextKey3] = oldRoutes = new Dictionary<ContentIdAndCulture, ContentKeyAndOldRoute>();
|
||||
return oldRoutes;
|
||||
}
|
||||
}
|
||||
@@ -58,27 +58,27 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
private static bool LockedEvents
|
||||
{
|
||||
get => Moving && UmbracoContext.Current.HttpContext.Items[ContextKey2] != null;
|
||||
get => Moving && Current.UmbracoContext.HttpContext.Items[ContextKey2] != null;
|
||||
set
|
||||
{
|
||||
if (Moving && value)
|
||||
UmbracoContext.Current.HttpContext.Items[ContextKey2] = true;
|
||||
Current.UmbracoContext.HttpContext.Items[ContextKey2] = true;
|
||||
else
|
||||
UmbracoContext.Current.HttpContext.Items.Remove(ContextKey2);
|
||||
Current.UmbracoContext.HttpContext.Items.Remove(ContextKey2);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool Moving
|
||||
{
|
||||
get => UmbracoContext.Current.HttpContext.Items[ContextKey1] != null;
|
||||
get => Current.UmbracoContext.HttpContext.Items[ContextKey1] != null;
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
UmbracoContext.Current.HttpContext.Items[ContextKey1] = true;
|
||||
Current.UmbracoContext.HttpContext.Items[ContextKey1] = true;
|
||||
else
|
||||
{
|
||||
UmbracoContext.Current.HttpContext.Items.Remove(ContextKey1);
|
||||
UmbracoContext.Current.HttpContext.Items.Remove(ContextKey2);
|
||||
Current.UmbracoContext.HttpContext.Items.Remove(ContextKey1);
|
||||
Current.UmbracoContext.HttpContext.Items.Remove(ContextKey2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,7 +164,7 @@ namespace Umbraco.Web.Routing
|
||||
{
|
||||
if (LockedEvents) return;
|
||||
|
||||
var contentCache = UmbracoContext.Current.ContentCache;
|
||||
var contentCache = Current.UmbracoContext.ContentCache;
|
||||
foreach (var entity in args.PublishedEntities)
|
||||
{
|
||||
var entityContent = contentCache.GetById(entity.Id);
|
||||
@@ -205,7 +205,7 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
private static void CreateRedirect(int contentId, string culture, Guid contentKey, string oldRoute)
|
||||
{
|
||||
var contentCache = UmbracoContext.Current.ContentCache;
|
||||
var contentCache = Current.UmbracoContext.ContentCache;
|
||||
var newRoute = contentCache.GetRouteById(contentId, culture);
|
||||
if (IsNotRoute(newRoute) || oldRoute == newRoute) return;
|
||||
var redirectUrlService = Current.Services.RedirectUrlService;
|
||||
|
||||
@@ -6,6 +6,7 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
@@ -210,7 +211,7 @@ namespace Umbraco.Web.Routing
|
||||
var provider = _urlProviders.OfType<DefaultUrlProvider>().FirstOrDefault();
|
||||
var url = provider == null
|
||||
? route // what else?
|
||||
: provider.GetUrlFromRoute(route, UmbracoContext.Current, id, _umbracoContext.CleanedUmbracoUrl, Mode, culture)?.Text;
|
||||
: provider.GetUrlFromRoute(route, Current.UmbracoContext, id, _umbracoContext.CleanedUmbracoUrl, Mode, culture)?.Text;
|
||||
return url ?? "#";
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace Umbraco.Web.Runtime
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
{
|
||||
// setup mvc and webapi services
|
||||
SetupMvcAndWebApi();
|
||||
|
||||
@@ -87,23 +87,6 @@ namespace Umbraco.Web.Runtime
|
||||
// set routes
|
||||
CreateRoutes(_umbracoContextAccessor, _globalSettings, _surfaceControllerTypes, _apiControllerTypes);
|
||||
|
||||
// get an http context
|
||||
// at that moment, HttpContext.Current != null but its .Request property is null
|
||||
var httpContext = new HttpContextWrapper(HttpContext.Current);
|
||||
|
||||
// ensure there is an UmbracoContext
|
||||
// (also sets the accessor)
|
||||
// this is a *temp* UmbracoContext
|
||||
UmbracoContext.EnsureContext(
|
||||
_umbracoContextAccessor,
|
||||
new HttpContextWrapper(HttpContext.Current),
|
||||
_publishedSnapshotService,
|
||||
new WebSecurity(httpContext, _userService, _globalSettings),
|
||||
_umbracoSettings,
|
||||
_urlProviders,
|
||||
_globalSettings,
|
||||
_variationContextAccessor);
|
||||
|
||||
// ensure WebAPI is initialized, after everything
|
||||
GlobalConfiguration.Configuration.EnsureInitialized();
|
||||
}
|
||||
|
||||
@@ -76,6 +76,9 @@ namespace Umbraco.Web.Runtime
|
||||
// let's use an hybrid accessor that can fall back to a ThreadStatic context.
|
||||
composition.RegisterUnique<IUmbracoContextAccessor, HybridUmbracoContextAccessor>();
|
||||
|
||||
// register the umbraco context factory
|
||||
composition.RegisterUnique<IUmbracoContextFactory, UmbracoContextFactory>();
|
||||
|
||||
// register a per-request HttpContextBase object
|
||||
// is per-request so only one wrapper is created per request
|
||||
composition.Register<HttpContextBase>(factory => new HttpContextWrapper(factory.GetInstance<IHttpContextAccessor>().HttpContext), Lifetime.Request);
|
||||
|
||||
@@ -11,14 +11,16 @@ namespace Umbraco.Web.Scheduling
|
||||
{
|
||||
private readonly IRuntimeState _runtime;
|
||||
private readonly IContentService _contentService;
|
||||
private readonly IUmbracoContextFactory _umbracoContextFactory;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public ScheduledPublishing(IBackgroundTaskRunner<RecurringTaskBase> runner, int delayMilliseconds, int periodMilliseconds,
|
||||
IRuntimeState runtime, IContentService contentService, ILogger logger)
|
||||
IRuntimeState runtime, IContentService contentService, IUmbracoContextFactory umbracoContextFactory, ILogger logger)
|
||||
: base(runner, delayMilliseconds, periodMilliseconds)
|
||||
{
|
||||
_runtime = runtime;
|
||||
_contentService = contentService;
|
||||
_umbracoContextFactory = umbracoContextFactory;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -62,7 +64,7 @@ namespace Umbraco.Web.Scheduling
|
||||
// but then what should be its "scope"? could we attach it to scopes?
|
||||
// - and we should definitively *not* have to flush it here (should be auto)
|
||||
//
|
||||
using (var tempContext = UmbracoContext.EnsureContext())
|
||||
using (var contextReference = _umbracoContextFactory.EnsureUmbracoContext())
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -74,7 +76,7 @@ namespace Umbraco.Web.Scheduling
|
||||
finally
|
||||
{
|
||||
// if running on a temp context, we have to flush the messenger
|
||||
if (tempContext != null && Composing.Current.ServerMessenger is BatchedDatabaseServerMessenger m)
|
||||
if (contextReference.IsRoot && Composing.Current.ServerMessenger is BatchedDatabaseServerMessenger m)
|
||||
m.FlushBatch();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace Umbraco.Web.Scheduling
|
||||
private readonly IScopeProvider _scopeProvider;
|
||||
private readonly HealthCheckCollection _healthChecks;
|
||||
private readonly HealthCheckNotificationMethodCollection _notifications;
|
||||
private readonly IUmbracoContextFactory _umbracoContextFactory;
|
||||
|
||||
private BackgroundTaskRunner<IBackgroundTask> _keepAliveRunner;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _publishingRunner;
|
||||
@@ -37,13 +38,14 @@ namespace Umbraco.Web.Scheduling
|
||||
public SchedulerComponent(IRuntimeState runtime,
|
||||
IContentService contentService, IAuditService auditService,
|
||||
HealthCheckCollection healthChecks, HealthCheckNotificationMethodCollection notifications,
|
||||
IScopeProvider scopeProvider, IProfilingLogger logger)
|
||||
IScopeProvider scopeProvider, IUmbracoContextFactory umbracoContextFactory, IProfilingLogger logger)
|
||||
{
|
||||
_runtime = runtime;
|
||||
_contentService = contentService;
|
||||
_auditService = auditService;
|
||||
_scopeProvider = scopeProvider;
|
||||
_logger = logger;
|
||||
_umbracoContextFactory = umbracoContextFactory;
|
||||
|
||||
_healthChecks = healthChecks;
|
||||
_notifications = notifications;
|
||||
@@ -113,11 +115,11 @@ namespace Umbraco.Web.Scheduling
|
||||
{
|
||||
// scheduled publishing/unpublishing
|
||||
// install on all, will only run on non-replica servers
|
||||
var task = new ScheduledPublishing(_publishingRunner, 60000, 60000, _runtime, _contentService, _logger);
|
||||
var task = new ScheduledPublishing(_publishingRunner, 60000, 60000, _runtime, _contentService, _umbracoContextFactory, _logger);
|
||||
_publishingRunner.TryAdd(task);
|
||||
return task;
|
||||
}
|
||||
|
||||
|
||||
private IBackgroundTask RegisterHealthCheckNotifier(IHealthChecks healthCheckConfig,
|
||||
HealthCheckCollection healthChecks, HealthCheckNotificationMethodCollection notifications,
|
||||
IProfilingLogger logger)
|
||||
|
||||
@@ -703,7 +703,7 @@ namespace Umbraco.Web.Security
|
||||
/// <returns></returns>
|
||||
public virtual Attempt<PasswordChangedModel> ChangePassword(string username, ChangingPasswordModel passwordModel, MembershipProvider membershipProvider)
|
||||
{
|
||||
var passwordChanger = new PasswordChanger(_logger, _userService, Web.Composing.Current.UmbracoContext.HttpContext);
|
||||
var passwordChanger = new PasswordChanger(_logger, _userService, UmbracoContext.HttpContext);
|
||||
return passwordChanger.ChangePasswordWithMembershipProvider(username, passwordModel, membershipProvider);
|
||||
}
|
||||
|
||||
|
||||
@@ -138,6 +138,7 @@
|
||||
<Compile Include="Editors\KeepAliveController.cs" />
|
||||
<Compile Include="Editors\MacrosController.cs" />
|
||||
<Compile Include="Editors\RelationTypeController.cs" />
|
||||
<Compile Include="IUmbracoContextFactory.cs" />
|
||||
<Compile Include="Install\ChangesMonitor.cs" />
|
||||
<Compile Include="Logging\WebProfiler.cs" />
|
||||
<Compile Include="Logging\WebProfilerComponent.cs" />
|
||||
@@ -208,6 +209,8 @@
|
||||
<Compile Include="Models\Link.cs" />
|
||||
<Compile Include="Models\LinkType.cs" />
|
||||
<Compile Include="Models\TemplateQuery\OperatorFactory.cs" />
|
||||
<Compile Include="UmbracoContextFactory.cs" />
|
||||
<Compile Include="UmbracoContextReference.cs" />
|
||||
<Compile Include="WebApi\Filters\OnlyLocalRequestsAttribute.cs" />
|
||||
<Compile Include="PropertyEditors\MultiUrlPickerConfiguration.cs" />
|
||||
<Compile Include="PropertyEditors\MultiUrlPickerConfigurationEditor.cs" />
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Composing;
|
||||
@@ -18,7 +16,7 @@ namespace Umbraco.Web
|
||||
/// <summary>
|
||||
/// Class that encapsulates Umbraco information of a specific HTTP request
|
||||
/// </summary>
|
||||
public class UmbracoContext : DisposableObject, IDisposeOnRequestEnd
|
||||
public class UmbracoContext : DisposableObjectSlim, IDisposeOnRequestEnd
|
||||
{
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly Lazy<IPublishedSnapshot> _publishedSnapshot;
|
||||
@@ -26,102 +24,6 @@ namespace Umbraco.Web
|
||||
private string _previewToken;
|
||||
private bool? _previewing;
|
||||
|
||||
#region Ensure Context
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that there is a "current" UmbracoContext.
|
||||
/// </summary>
|
||||
/// <param name="umbracoContextAccessor"></param>
|
||||
/// <param name="httpContext">An http context.</param>
|
||||
/// <param name="publishedSnapshotService">A published snapshot service.</param>
|
||||
/// <param name="webSecurity">A security helper.</param>
|
||||
/// <param name="umbracoSettings">The umbraco settings.</param>
|
||||
/// <param name="urlProviders">Some url providers.</param>
|
||||
/// <param name="globalSettings"></param>
|
||||
/// <param name="replace">A value indicating whether to replace the existing context.</param>
|
||||
/// <returns>The "current" UmbracoContext.</returns>
|
||||
/// <remarks>
|
||||
/// TODO: this needs to be clarified
|
||||
///
|
||||
/// If <paramref name="replace"/> is true then the "current" UmbracoContext is replaced
|
||||
/// with a new one even if there is one already. See <see cref="WebRuntimeComponent"/>. Has to do with
|
||||
/// creating a context at startup and not being able to access httpContext.Request at that time, so
|
||||
/// the OriginalRequestUrl remains unspecified until <see cref="UmbracoModule"/> replaces the context.
|
||||
///
|
||||
/// This *has* to be done differently!
|
||||
///
|
||||
/// See http://issues.umbraco.org/issue/U4-1890, http://issues.umbraco.org/issue/U4-1717
|
||||
///
|
||||
/// </remarks>
|
||||
// used by
|
||||
// UmbracoModule BeginRequest (since it's a request it has an UmbracoContext)
|
||||
// in BeginRequest so *late* ie *after* the HttpApplication has started (+ init? check!)
|
||||
// WebRuntimeComponent (and I'm not quite sure why)
|
||||
// -> because an UmbracoContext seems to be required by UrlProvider to get the "current" published snapshot?
|
||||
// note: at startup not sure we have an HttpContext.Current
|
||||
// at startup not sure we have an httpContext.Request => hard to tell "current" url
|
||||
// should we have a post-boot event of some sort for ppl that *need* ?!
|
||||
// can we have issues w/ routing context?
|
||||
// and tests
|
||||
// can .ContentRequest be null? of course!
|
||||
public static UmbracoContext EnsureContext(
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
HttpContextBase httpContext,
|
||||
IPublishedSnapshotService publishedSnapshotService,
|
||||
WebSecurity webSecurity,
|
||||
IUmbracoSettingsSection umbracoSettings,
|
||||
IEnumerable<IUrlProvider> urlProviders,
|
||||
IGlobalSettings globalSettings,
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
bool replace = false)
|
||||
{
|
||||
if (umbracoContextAccessor == null) throw new ArgumentNullException(nameof(umbracoContextAccessor));
|
||||
if (httpContext == null) throw new ArgumentNullException(nameof(httpContext));
|
||||
if (publishedSnapshotService == null) throw new ArgumentNullException(nameof(publishedSnapshotService));
|
||||
if (webSecurity == null) throw new ArgumentNullException(nameof(webSecurity));
|
||||
if (umbracoSettings == null) throw new ArgumentNullException(nameof(umbracoSettings));
|
||||
if (urlProviders == null) throw new ArgumentNullException(nameof(urlProviders));
|
||||
if (globalSettings == null) throw new ArgumentNullException(nameof(globalSettings));
|
||||
|
||||
// if there is already a current context, return if not replacing
|
||||
var current = umbracoContextAccessor.UmbracoContext;
|
||||
if (current != null && replace == false)
|
||||
return current;
|
||||
|
||||
// create & assign to accessor, dispose existing if any
|
||||
umbracoContextAccessor.UmbracoContext?.Dispose();
|
||||
return umbracoContextAccessor.UmbracoContext = new UmbracoContext(httpContext, publishedSnapshotService, webSecurity, umbracoSettings, urlProviders, globalSettings, variationContextAccessor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a disposable object representing the presence of a current UmbracoContext.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The disposable object should be used in a using block: using (UmbracoContext.EnsureContext()) { ... }.</para>
|
||||
/// <para>If an actual current UmbracoContext is already present, the disposable object is null and this method does nothing.</para>
|
||||
/// <para>Otherwise, a temporary, dummy UmbracoContext is created and registered in the accessor. And disposed and removed from the accessor.</para>
|
||||
/// </remarks>
|
||||
internal static IDisposable EnsureContext(HttpContextBase httpContext = null) // keep this internal for now!
|
||||
{
|
||||
if (Composing.Current.UmbracoContext != null) return null;
|
||||
|
||||
httpContext = httpContext ?? new HttpContextWrapper(System.Web.HttpContext.Current ?? new HttpContext(new SimpleWorkerRequest("temp.aspx", "", new StringWriter())));
|
||||
|
||||
return EnsureContext(
|
||||
Composing.Current.UmbracoContextAccessor,
|
||||
httpContext,
|
||||
Composing.Current.PublishedSnapshotService,
|
||||
new WebSecurity(httpContext, Composing.Current.Services.UserService, Composing.Current.Configs.Global()),
|
||||
Composing.Current.Configs.Settings(),
|
||||
Composing.Current.UrlProviders,
|
||||
Composing.Current.Configs.Global(),
|
||||
Composing.Current.Factory.GetInstance<IVariationContextAccessor>(),
|
||||
true);
|
||||
|
||||
// when the context will be disposed, it will be removed from the accessor
|
||||
// (see DisposeResources)
|
||||
}
|
||||
|
||||
// initializes a new instance of the UmbracoContext class
|
||||
// internal for unit tests
|
||||
// otherwise it's used by EnsureContext above
|
||||
@@ -172,14 +74,6 @@ namespace Umbraco.Web
|
||||
UrlProvider = new UrlProvider(this, umbracoSettings.WebRouting, urlProviders, variationContextAccessor);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current Umbraco Context.
|
||||
/// </summary>
|
||||
// note: obsolete, use Current.UmbracoContext... then obsolete Current too, and inject!
|
||||
public static UmbracoContext Current => Composing.Current.UmbracoContext;
|
||||
|
||||
/// <summary>
|
||||
/// This is used internally for performance calculations, the ObjectCreated DateTime is set as soon as this
|
||||
/// object is instantiated which in the web site is created during the BeginRequest phase.
|
||||
@@ -281,7 +175,7 @@ namespace Umbraco.Web
|
||||
|| string.IsNullOrEmpty(request["umbdebug"]) == false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the current user is in a preview mode and browsing the site (ie. not in the admin UI)
|
||||
/// </summary>
|
||||
@@ -345,15 +239,11 @@ namespace Umbraco.Web
|
||||
|
||||
Security.DisposeIfDisposable();
|
||||
|
||||
// reset - important when running outside of http context
|
||||
// also takes care of the accessor
|
||||
Composing.Current.ClearUmbracoContext();
|
||||
|
||||
// help caches release resources
|
||||
// (but don't create caches just to dispose them)
|
||||
// context is not multi-threaded
|
||||
if (_publishedSnapshot.IsValueCreated)
|
||||
_publishedSnapshot.Value.DisposeIfDisposable();
|
||||
_publishedSnapshot.Value.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
83
src/Umbraco.Web/UmbracoContextFactory.cs
Normal file
83
src/Umbraco.Web/UmbracoContextFactory.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Hosting;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web.Routing;
|
||||
using Umbraco.Web.Security;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates and manages <see cref="UmbracoContext"/> instances.
|
||||
/// </summary>
|
||||
public class UmbracoContextFactory : IUmbracoContextFactory
|
||||
{
|
||||
private static readonly NullWriter NullWriterInstance = new NullWriter();
|
||||
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly IPublishedSnapshotService _publishedSnapshotService;
|
||||
private readonly IVariationContextAccessor _variationContextAccessor;
|
||||
private readonly IDefaultCultureAccessor _defaultCultureAccessor;
|
||||
|
||||
private readonly IUmbracoSettingsSection _umbracoSettings;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly IEnumerable<IUrlProvider> _urlProviders;
|
||||
private readonly IUserService _userService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoContextFactory"/> class.
|
||||
/// </summary>
|
||||
public UmbracoContextFactory(IUmbracoContextAccessor umbracoContextAccessor, IPublishedSnapshotService publishedSnapshotService, IVariationContextAccessor variationContextAccessor, IDefaultCultureAccessor defaultCultureAccessor, IUmbracoSettingsSection umbracoSettings, IGlobalSettings globalSettings, IEnumerable<IUrlProvider> urlProviders, IUserService userService)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor));
|
||||
_publishedSnapshotService = publishedSnapshotService ?? throw new ArgumentNullException(nameof(publishedSnapshotService));
|
||||
_variationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor));
|
||||
_defaultCultureAccessor = defaultCultureAccessor ?? throw new ArgumentNullException(nameof(defaultCultureAccessor));
|
||||
|
||||
_umbracoSettings = umbracoSettings ?? throw new ArgumentNullException(nameof(umbracoSettings));
|
||||
_globalSettings = globalSettings ?? throw new ArgumentNullException(nameof(globalSettings));
|
||||
_urlProviders = urlProviders ?? throw new ArgumentNullException(nameof(urlProviders));
|
||||
_userService = userService ?? throw new ArgumentNullException(nameof(userService));
|
||||
}
|
||||
|
||||
private UmbracoContext CreateUmbracoContext(HttpContextBase httpContext)
|
||||
{
|
||||
// make sure we have a variation context
|
||||
if (_variationContextAccessor.VariationContext == null)
|
||||
_variationContextAccessor.VariationContext = new VariationContext(_defaultCultureAccessor.DefaultCulture);
|
||||
|
||||
var webSecurity = new WebSecurity(httpContext, _userService, _globalSettings);
|
||||
|
||||
return new UmbracoContext(httpContext, _publishedSnapshotService, webSecurity, _umbracoSettings, _urlProviders, _globalSettings, _variationContextAccessor);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public UmbracoContextReference EnsureUmbracoContext(HttpContextBase httpContext = null)
|
||||
{
|
||||
var currentUmbracoContext = _umbracoContextAccessor.UmbracoContext;
|
||||
if (currentUmbracoContext != null)
|
||||
return new UmbracoContextReference(currentUmbracoContext, false, _umbracoContextAccessor);
|
||||
|
||||
|
||||
httpContext = httpContext ?? new HttpContextWrapper(HttpContext.Current ?? new HttpContext(new SimpleWorkerRequest("null.aspx", "", NullWriterInstance)));
|
||||
|
||||
var umbracoContext = CreateUmbracoContext(httpContext);
|
||||
_umbracoContextAccessor.UmbracoContext = umbracoContext;
|
||||
|
||||
return new UmbracoContextReference(umbracoContext, true, _umbracoContextAccessor);
|
||||
}
|
||||
|
||||
// dummy TextWriter that does not write
|
||||
private class NullWriter : TextWriter
|
||||
{
|
||||
public override Encoding Encoding => Encoding.UTF8;
|
||||
}
|
||||
}
|
||||
}
|
||||
60
src/Umbraco.Web/UmbracoContextReference.cs
Normal file
60
src/Umbraco.Web/UmbracoContextReference.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a reference to an <see cref="UmbracoContext"/> instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>A reference points to an <see cref="UmbracoContext"/> and it may own it (when it
|
||||
/// is a root reference) or just reference it. A reference must be disposed after it has
|
||||
/// been used. Disposing does nothing if the reference is not a root reference. Otherwise,
|
||||
/// it disposes the <see cref="UmbracoContext"/> and clears the
|
||||
/// <see cref="IUmbracoContextAccessor"/>.</para>
|
||||
/// </remarks>
|
||||
public class UmbracoContextReference : IDisposable //fixme - should we inherit from DisposableObjectSlim?
|
||||
{
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoContextReference"/> class.
|
||||
/// </summary>
|
||||
internal UmbracoContextReference(UmbracoContext umbracoContext, bool isRoot, IUmbracoContextAccessor umbracoContextAccessor)
|
||||
{
|
||||
UmbracoContext = umbracoContext;
|
||||
IsRoot = isRoot;
|
||||
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="UmbracoContext"/>.
|
||||
/// </summary>
|
||||
public UmbracoContext UmbracoContext { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the reference is a root reference.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para></para>
|
||||
/// </remarks>
|
||||
public bool IsRoot { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
_disposed = true;
|
||||
|
||||
if (IsRoot)
|
||||
{
|
||||
UmbracoContext.Dispose();
|
||||
_umbracoContextAccessor.UmbracoContext = null;
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,7 @@ namespace Umbraco.Web
|
||||
private readonly ILogger _logger;
|
||||
private readonly IPublishedRouter _publishedRouter;
|
||||
private readonly IVariationContextAccessor _variationContextAccessor;
|
||||
private readonly IUmbracoContextFactory _umbracoContextFactory;
|
||||
|
||||
public UmbracoInjectedModule(
|
||||
IGlobalSettings globalSettings,
|
||||
@@ -57,7 +58,8 @@ namespace Umbraco.Web
|
||||
IRuntimeState runtime,
|
||||
ILogger logger,
|
||||
IPublishedRouter publishedRouter,
|
||||
IVariationContextAccessor variationContextAccessor)
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
IUmbracoContextFactory umbracoContextFactory)
|
||||
{
|
||||
_combinedRouteCollection = new Lazy<RouteCollection>(CreateRouteCollection);
|
||||
|
||||
@@ -70,6 +72,7 @@ namespace Umbraco.Web
|
||||
_logger = logger;
|
||||
_publishedRouter = publishedRouter;
|
||||
_variationContextAccessor = variationContextAccessor;
|
||||
_umbracoContextFactory = umbracoContextFactory;
|
||||
}
|
||||
|
||||
#region HttpModule event handlers
|
||||
@@ -92,18 +95,10 @@ namespace Umbraco.Web
|
||||
|
||||
// ok, process
|
||||
|
||||
// create the UmbracoContext singleton, one per request, and assign
|
||||
// replace existing if any (eg during app startup, a temp one is created)
|
||||
UmbracoContext.EnsureContext(
|
||||
_umbracoContextAccessor,
|
||||
httpContext,
|
||||
_publishedSnapshotService,
|
||||
new WebSecurity(httpContext, _userService, _globalSettings),
|
||||
Current.Configs.Settings(),
|
||||
_urlProviders,
|
||||
_globalSettings,
|
||||
_variationContextAccessor,
|
||||
true);
|
||||
// ensure there's an UmbracoContext registered for the current request
|
||||
// registers the context reference so its disposed at end of request
|
||||
var umbracoContextReference = _umbracoContextFactory.EnsureUmbracoContext(httpContext);
|
||||
httpContext.DisposeOnPipelineCompleted(umbracoContextReference);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -124,10 +119,10 @@ namespace Umbraco.Web
|
||||
if (httpContext.Request.Url.IsClientSideRequest())
|
||||
return;
|
||||
|
||||
if (UmbracoContext.Current == null)
|
||||
throw new InvalidOperationException("The UmbracoContext.Current is null, ProcessRequest cannot proceed unless there is a current UmbracoContext");
|
||||
if (Current.UmbracoContext == null)
|
||||
throw new InvalidOperationException("The Current.UmbracoContext is null, ProcessRequest cannot proceed unless there is a current UmbracoContext");
|
||||
|
||||
var umbracoContext = UmbracoContext.Current;
|
||||
var umbracoContext = Current.UmbracoContext;
|
||||
|
||||
// re-write for the default back office path
|
||||
if (httpContext.Request.Url.IsDefaultBackOfficeRequest(_globalSettings))
|
||||
@@ -491,14 +486,14 @@ namespace Umbraco.Web
|
||||
{
|
||||
var httpContext = ((HttpApplication) sender).Context;
|
||||
|
||||
if (UmbracoContext.Current != null && UmbracoContext.Current.IsFrontEndUmbracoRequest)
|
||||
if (Current.UmbracoContext != null && Current.UmbracoContext.IsFrontEndUmbracoRequest)
|
||||
{
|
||||
LogHttpRequest.TryGetCurrentHttpRequestId(out var httpRequestId);
|
||||
|
||||
_logger.Verbose<UmbracoModule>("End Request [{HttpRequestId}]: {RequestUrl} ({RequestDuration}ms)", httpRequestId, httpContext.Request.Url, DateTime.Now.Subtract(UmbracoContext.Current.ObjectCreated).TotalMilliseconds);
|
||||
_logger.Verbose<UmbracoModule>("End Request [{HttpRequestId}]: {RequestUrl} ({RequestDuration}ms)", httpRequestId, httpContext.Request.Url, DateTime.Now.Subtract(Current.UmbracoContext.ObjectCreated).TotalMilliseconds);
|
||||
}
|
||||
|
||||
UmbracoModule.OnEndRequest(this, new UmbracoRequestEventArgs(UmbracoContext.Current, new HttpContextWrapper(httpContext)));
|
||||
UmbracoModule.OnEndRequest(this, new UmbracoRequestEventArgs(Current.UmbracoContext, new HttpContextWrapper(httpContext)));
|
||||
|
||||
DisposeHttpContextItems(httpContext);
|
||||
};
|
||||
|
||||
@@ -296,7 +296,7 @@ namespace Umbraco.Web
|
||||
|
||||
var encryptedRoute = UmbracoHelper.CreateEncryptedRouteString(controllerName, action, area, additionalRouteVals);
|
||||
|
||||
var result = UmbracoContext.Current.OriginalRequestUrl.AbsolutePath.EnsureEndsWith('?') + "ufprt=" + encryptedRoute;
|
||||
var result = Current.UmbracoContext.OriginalRequestUrl.AbsolutePath.EnsureEndsWith('?') + "ufprt=" + encryptedRoute;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ namespace Umbraco.Web
|
||||
|
||||
var encryptedRoute = UmbracoHelper.CreateEncryptedRouteString(metaData.ControllerName, action, area, additionalRouteVals);
|
||||
|
||||
var result = UmbracoContext.Current.OriginalRequestUrl.AbsolutePath.EnsureEndsWith('?') + "ufprt=" + encryptedRoute;
|
||||
var result = Current.UmbracoContext.OriginalRequestUrl.AbsolutePath.EnsureEndsWith('?') + "ufprt=" + encryptedRoute;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
{
|
||||
if (context.Response == null) return;
|
||||
if (context.Request.Method == HttpMethod.Get) return;
|
||||
if (UmbracoContext.Current == null) return;
|
||||
if (Current.UmbracoContext == null) return;
|
||||
|
||||
var obj = context.Response.Content as ObjectContent;
|
||||
if (obj == null) return;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Web.Http.Filters;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Composing;
|
||||
|
||||
namespace Umbraco.Web.WebApi.Filters
|
||||
{
|
||||
@@ -53,7 +54,7 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
throw new InvalidOperationException("No argument found for the current action with the name: " + _userIdParameter);
|
||||
}
|
||||
|
||||
var user = UmbracoContext.Current.Security.CurrentUser;
|
||||
var user = Current.UmbracoContext.Security.CurrentUser;
|
||||
if (user == null) return;
|
||||
|
||||
var userId = GetUserIdFromParameter(actionContext.ActionArguments[_userIdParameter]);
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
|
||||
public override void OnActionExecuting(HttpActionContext actionContext)
|
||||
{
|
||||
if (UmbracoContext.Current.Security.CurrentUser == null)
|
||||
if (Current.UmbracoContext.Security.CurrentUser == null)
|
||||
{
|
||||
//not logged in
|
||||
throw new HttpResponseException(System.Net.HttpStatusCode.Unauthorized);
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
|
||||
public override void OnActionExecuting(HttpActionContext actionContext)
|
||||
{
|
||||
if (UmbracoContext.Current.Security.CurrentUser == null)
|
||||
if (Current.UmbracoContext.Security.CurrentUser == null)
|
||||
{
|
||||
throw new HttpResponseException(System.Net.HttpStatusCode.Unauthorized);
|
||||
}
|
||||
@@ -118,7 +118,7 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
|
||||
if (MediaController.CheckPermissions(
|
||||
actionContext.Request.Properties,
|
||||
UmbracoContext.Current.Security.CurrentUser,
|
||||
Current.UmbracoContext.Security.CurrentUser,
|
||||
Current.Services.MediaService,
|
||||
Current.Services.EntityService,
|
||||
nodeId))
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
{
|
||||
if (actionExecutedContext.Response == null) return;
|
||||
|
||||
var user = UmbracoContext.Current.Security.CurrentUser;
|
||||
var user = Composing.Current.UmbracoContext.Security.CurrentUser;
|
||||
if (user == null) return;
|
||||
|
||||
var objectContent = actionExecutedContext.Response.Content as ObjectContent;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Net.Http;
|
||||
using System.Web.Http.Filters;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Editors;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
@@ -16,7 +17,7 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
{
|
||||
if (actionExecutedContext.Response == null) return;
|
||||
|
||||
var user = UmbracoContext.Current.Security.CurrentUser;
|
||||
var user = Current.UmbracoContext.Security.CurrentUser;
|
||||
if (user == null) return;
|
||||
|
||||
if (actionExecutedContext.Response.Content is ObjectContent objectContent)
|
||||
@@ -27,7 +28,7 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
{
|
||||
var args = new EditorModelEventArgs(
|
||||
model,
|
||||
UmbracoContext.Current);
|
||||
Current.UmbracoContext);
|
||||
EditorModelEventManager.EmitEvent(actionExecutedContext, args);
|
||||
objectContent.Value = args.Model;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user