@@ -6,7 +6,7 @@ using System.Text;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class FileSystemProviderElement : ConfigurationElement
|
||||
public class FileSystemProviderElement : ConfigurationElement, IFileSystemProviderElement
|
||||
{
|
||||
private const string ALIAS_KEY = "alias";
|
||||
private const string TYPE_KEY = "type";
|
||||
@@ -38,5 +38,30 @@ namespace Umbraco.Core.Configuration
|
||||
return ((KeyValueConfigurationCollection)(base[PARAMETERS_KEY]));
|
||||
}
|
||||
}
|
||||
|
||||
string IFileSystemProviderElement.Alias
|
||||
{
|
||||
get { return Alias; }
|
||||
}
|
||||
|
||||
string IFileSystemProviderElement.Type
|
||||
{
|
||||
get { return Type; }
|
||||
}
|
||||
|
||||
private IDictionary<string, string> _params;
|
||||
IDictionary<string, string> IFileSystemProviderElement.Parameters
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_params != null) return _params;
|
||||
_params = new Dictionary<string, string>();
|
||||
foreach (KeyValueConfigurationElement element in Parameters)
|
||||
{
|
||||
_params.Add(element.Key, element.Value);
|
||||
}
|
||||
return _params;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ using System.Text;
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
[ConfigurationCollection(typeof(FileSystemProviderElement), AddItemName = "Provider")]
|
||||
public class FileSystemProviderElementCollection : ConfigurationElementCollection
|
||||
public class FileSystemProviderElementCollection : ConfigurationElementCollection, IEnumerable<IFileSystemProviderElement>
|
||||
{
|
||||
protected override ConfigurationElement CreateNewElement()
|
||||
{
|
||||
@@ -19,12 +19,25 @@ namespace Umbraco.Core.Configuration
|
||||
return ((FileSystemProviderElement)(element)).Alias;
|
||||
}
|
||||
|
||||
new public FileSystemProviderElement this[string key]
|
||||
public new FileSystemProviderElement this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return (FileSystemProviderElement)BaseGet(key);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator<IFileSystemProviderElement> IEnumerable<IFileSystemProviderElement>.GetEnumerator()
|
||||
{
|
||||
for (var i = 0; i < Count; i++)
|
||||
{
|
||||
yield return BaseGet(i) as IFileSystemProviderElement;
|
||||
}
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Text;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class FileSystemProvidersSection : ConfigurationSection
|
||||
public class FileSystemProvidersSection : ConfigurationSection, IFileSystemProvidersSection
|
||||
{
|
||||
|
||||
[ConfigurationProperty("", IsDefaultCollection = true, IsRequired = true)]
|
||||
@@ -14,5 +14,17 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get { return ((FileSystemProviderElementCollection)(base[""])); }
|
||||
}
|
||||
|
||||
private IDictionary<string, IFileSystemProviderElement> _providers;
|
||||
|
||||
IDictionary<string, IFileSystemProviderElement> IFileSystemProvidersSection.Providers
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_providers != null) return _providers;
|
||||
_providers = Providers.ToDictionary(x => x.Alias, x => x);
|
||||
return _providers;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
src/Umbraco.Core/Configuration/IFileSystemProviderElement.cs
Normal file
11
src/Umbraco.Core/Configuration/IFileSystemProviderElement.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public interface IFileSystemProviderElement
|
||||
{
|
||||
string Alias { get; }
|
||||
string Type { get; }
|
||||
IDictionary<string, string> Parameters { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public interface IFileSystemProvidersSection
|
||||
{
|
||||
IDictionary<string, IFileSystemProviderElement> Providers { get; }
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Core.IO
|
||||
{
|
||||
public class FileSystemProviderManager
|
||||
{
|
||||
private readonly FileSystemProvidersSection _config;
|
||||
private readonly IFileSystemProvidersSection _config;
|
||||
private readonly ConcurrentSet<ShadowWrapper> _wrappers = new ConcurrentSet<ShadowWrapper>();
|
||||
|
||||
private readonly ConcurrentDictionary<string, ProviderConstructionInfo> _providerLookup = new ConcurrentDictionary<string, ProviderConstructionInfo>();
|
||||
@@ -28,16 +28,45 @@ namespace Umbraco.Core.IO
|
||||
private ShadowWrapper _mvcViewsFileSystem;
|
||||
|
||||
#region Singleton & Constructor
|
||||
|
||||
private static readonly FileSystemProviderManager Instance = new FileSystemProviderManager();
|
||||
|
||||
private static volatile FileSystemProviderManager _instance;
|
||||
private static readonly object _instanceLocker = new object();
|
||||
|
||||
public static FileSystemProviderManager Current
|
||||
{
|
||||
get { return Instance; }
|
||||
get
|
||||
{
|
||||
if (_instance != null) return _instance;
|
||||
lock (_instanceLocker)
|
||||
{
|
||||
return _instance ?? (_instance = new FileSystemProviderManager());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For tests only, allows setting the value of the singleton "Current" property
|
||||
/// </summary>
|
||||
/// <param name="instance"></param>
|
||||
public static void SetCurrent(FileSystemProviderManager instance)
|
||||
{
|
||||
lock (_instanceLocker)
|
||||
{
|
||||
_instance = instance;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ResetCurrent()
|
||||
{
|
||||
lock (_instanceLocker)
|
||||
{
|
||||
if (_instance != null)
|
||||
_instance.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
// for tests only, totally unsafe
|
||||
internal void Reset()
|
||||
private void Reset()
|
||||
{
|
||||
_wrappers.Clear();
|
||||
_providerLookup.Clear();
|
||||
@@ -52,10 +81,24 @@ namespace Umbraco.Core.IO
|
||||
// beware: means that we capture the "current" scope provider - take care in tests!
|
||||
get { return ApplicationContext.Current == null ? null : ApplicationContext.Current.ScopeProvider as IScopeProviderInternal; }
|
||||
}
|
||||
|
||||
internal FileSystemProviderManager()
|
||||
|
||||
/// <summary>
|
||||
/// Constructor that can be used for tests
|
||||
/// </summary>
|
||||
/// <param name="configSection"></param>
|
||||
public FileSystemProviderManager(IFileSystemProvidersSection configSection)
|
||||
{
|
||||
_config = (FileSystemProvidersSection) ConfigurationManager.GetSection("umbracoConfiguration/FileSystemProviders");
|
||||
if (configSection == null) throw new ArgumentNullException("configSection");
|
||||
_config = configSection;
|
||||
CreateWellKnownFileSystems();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor that will read the config from the locally found config section
|
||||
/// </summary>
|
||||
public FileSystemProviderManager()
|
||||
{
|
||||
_config = (FileSystemProvidersSection)ConfigurationManager.GetSection("umbracoConfiguration/FileSystemProviders");
|
||||
CreateWellKnownFileSystems();
|
||||
}
|
||||
|
||||
@@ -150,8 +193,9 @@ namespace Umbraco.Core.IO
|
||||
private ProviderConstructionInfo GetUnderlyingFileSystemCtor(string alias, Func<IFileSystem> fallback)
|
||||
{
|
||||
// get config
|
||||
var providerConfig = _config.Providers[alias];
|
||||
if (providerConfig == null)
|
||||
IFileSystemProviderElement providerConfig;
|
||||
|
||||
if (_config.Providers.TryGetValue(alias, out providerConfig) == false)
|
||||
{
|
||||
if (fallback != null) return null;
|
||||
throw new ArgumentException(string.Format("No provider found with alias {0}.", alias));
|
||||
@@ -166,17 +210,21 @@ namespace Umbraco.Core.IO
|
||||
if (providerType.IsAssignableFrom(typeof(IFileSystem)))
|
||||
throw new InvalidOperationException(string.Format("Type {0} does not implement IFileSystem.", providerType.FullName));
|
||||
|
||||
// find a ctor matching the config parameters
|
||||
// find a ctor matching the config parameters
|
||||
var paramCount = providerConfig.Parameters != null ? providerConfig.Parameters.Count : 0;
|
||||
var constructor = providerType.GetConstructors().SingleOrDefault(x
|
||||
=> x.GetParameters().Length == paramCount && x.GetParameters().All(y => providerConfig.Parameters.AllKeys.Contains(y.Name)));
|
||||
=> x.GetParameters().Length == paramCount && x.GetParameters().All(y => providerConfig.Parameters.Keys.Contains(y.Name)));
|
||||
if (constructor == null)
|
||||
throw new InvalidOperationException(string.Format("Type {0} has no ctor matching the {1} configuration parameter(s).", providerType.FullName, paramCount));
|
||||
|
||||
var parameters = new object[paramCount];
|
||||
if (providerConfig.Parameters != null) // keeps ReSharper happy
|
||||
|
||||
if (providerConfig.Parameters != null)
|
||||
{
|
||||
var allKeys = providerConfig.Parameters.Keys.ToArray();
|
||||
for (var i = 0; i < paramCount; i++)
|
||||
parameters[i] = providerConfig.Parameters[providerConfig.Parameters.AllKeys[i]].Value;
|
||||
parameters[i] = providerConfig.Parameters[allKeys[i]];
|
||||
}
|
||||
|
||||
return new ProviderConstructionInfo
|
||||
{
|
||||
|
||||
@@ -241,6 +241,8 @@
|
||||
<Compile Include="Configuration\Grid\IGridConfig.cs" />
|
||||
<Compile Include="Configuration\Grid\IGridEditorConfig.cs" />
|
||||
<Compile Include="Configuration\Grid\IGridEditorsConfig.cs" />
|
||||
<Compile Include="Configuration\IFileSystemProviderElement.cs" />
|
||||
<Compile Include="Configuration\IFileSystemProvidersSection.cs" />
|
||||
<Compile Include="Configuration\UmbracoConfig.cs" />
|
||||
<Compile Include="Configuration\UmbracoConfigurationSection.cs" />
|
||||
<Compile Include="Configuration\UmbracoSettings\AppCodeFileExtensionsCollection.cs" />
|
||||
|
||||
@@ -26,14 +26,14 @@ namespace Umbraco.Tests.IO
|
||||
|
||||
// start clean
|
||||
// because some tests will create corrupt or weird filesystems
|
||||
FileSystemProviderManager.Current.Reset();
|
||||
FileSystemProviderManager.ResetCurrent();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
// stay clean (see note in SetUp)
|
||||
FileSystemProviderManager.Current.Reset();
|
||||
FileSystemProviderManager.ResetCurrent();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace Umbraco.Tests.TestHelpers
|
||||
// FileSystemProviderManager captures the current ApplicationContext ScopeProvider
|
||||
// in its current static instance (yea...) so we need to reset it here to ensure
|
||||
// it is using the proper ScopeProvider
|
||||
FileSystemProviderManager.Current.Reset();
|
||||
FileSystemProviderManager.ResetCurrent();
|
||||
}
|
||||
|
||||
protected virtual ApplicationContext CreateApplicationContext()
|
||||
|
||||
Reference in New Issue
Block a user