2019-02-14 12:51:46 +01:00
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
{
2019-02-15 10:42:02 +11:00
private static readonly NullWriter NullWriterInstance = new NullWriter ( ) ;
2019-02-14 12:51:46 +01:00
private readonly IUmbracoContextAccessor _umbracoContextAccessor ;
private readonly IPublishedSnapshotService _publishedSnapshotService ;
private readonly IVariationContextAccessor _variationContextAccessor ;
private readonly IDefaultCultureAccessor _defaultCultureAccessor ;
private readonly IUmbracoSettingsSection _umbracoSettings ;
private readonly IGlobalSettings _globalSettings ;
2019-03-11 15:36:39 +01:00
private readonly UrlProviderCollection _urlProviders ;
2019-04-15 15:57:35 +02:00
private readonly MediaUrlProviderCollection _mediaUrlProviders ;
2019-02-14 12:51:46 +01:00
private readonly IUserService _userService ;
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoContextFactory"/> class.
/// </summary>
2019-04-15 15:57:35 +02:00
public UmbracoContextFactory ( IUmbracoContextAccessor umbracoContextAccessor , IPublishedSnapshotService publishedSnapshotService , IVariationContextAccessor variationContextAccessor , IDefaultCultureAccessor defaultCultureAccessor , IUmbracoSettingsSection umbracoSettings , IGlobalSettings globalSettings , UrlProviderCollection urlProviders , MediaUrlProviderCollection mediaUrlProviders , IUserService userService )
2019-02-14 12:51:46 +01:00
{
_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 ) ) ;
2019-04-15 15:57:35 +02:00
_mediaUrlProviders = mediaUrlProviders ? ? throw new ArgumentNullException ( nameof ( mediaUrlProviders ) ) ;
2019-02-14 12:51:46 +01:00
_userService = userService ? ? throw new ArgumentNullException ( nameof ( userService ) ) ;
}
private UmbracoContext CreateUmbracoContext ( HttpContextBase httpContext )
{
// make sure we have a variation context
if ( _variationContextAccessor . VariationContext = = null )
2019-07-12 13:15:41 +10:00
{
// TODO: By using _defaultCultureAccessor.DefaultCulture this means that the VariationContext will always return a variant culture, it will never
// return an empty string signifying that the culture is invariant. But does this matter? Are we actually expecting this to return an empty string
// for invariant routes? From what i can tell throughout the codebase is that whenever we are checking against the VariationContext.Culture we are
// also checking if the content type varies by culture or not. This is fine, however the code in the ctor of VariationContext is then misleading
// since it's assuming that the Culture can be empty (invariant) when in reality of a website this will never be empty since a real culture is always set here.
2019-02-14 12:51:46 +01:00
_variationContextAccessor . VariationContext = new VariationContext ( _defaultCultureAccessor . DefaultCulture ) ;
2019-07-12 13:15:41 +10:00
}
2019-02-14 12:51:46 +01:00
var webSecurity = new WebSecurity ( httpContext , _userService , _globalSettings ) ;
2019-04-15 15:57:35 +02:00
return new UmbracoContext ( httpContext , _publishedSnapshotService , webSecurity , _umbracoSettings , _urlProviders , _mediaUrlProviders , _globalSettings , _variationContextAccessor ) ;
2019-02-14 12:51:46 +01:00
}
/// <inheritdoc />
public UmbracoContextReference EnsureUmbracoContext ( HttpContextBase httpContext = null )
{
var currentUmbracoContext = _umbracoContextAccessor . UmbracoContext ;
2019-06-20 17:58:40 +10:00
if ( currentUmbracoContext ! = null )
2019-02-14 12:51:46 +01:00
return new UmbracoContextReference ( currentUmbracoContext , false , _umbracoContextAccessor ) ;
2019-03-11 15:36:39 +01:00
2019-02-15 10:42:02 +11:00
httpContext = httpContext ? ? new HttpContextWrapper ( HttpContext . Current ? ? new HttpContext ( new SimpleWorkerRequest ( "null.aspx" , "" , NullWriterInstance ) ) ) ;
2019-02-14 12:51:46 +01:00
var umbracoContext = CreateUmbracoContext ( httpContext ) ;
_umbracoContextAccessor . UmbracoContext = umbracoContext ;
return new UmbracoContextReference ( umbracoContext , true , _umbracoContextAccessor ) ;
}
// dummy TextWriter that does not write
2019-02-15 10:42:02 +11:00
private class NullWriter : TextWriter
2019-02-14 12:51:46 +01:00
{
public override Encoding Encoding = > Encoding . UTF8 ;
}
}
2019-02-15 10:42:02 +11:00
}