More filesystem DI fixes
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
using System.Configuration;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.IO.MediaPathSchemes;
|
||||
|
||||
namespace Umbraco.Core.Composing.Composers
|
||||
{
|
||||
@@ -13,34 +14,45 @@ namespace Umbraco.Core.Composing.Composers
|
||||
*
|
||||
* Create a component and use it to modify the composition by adding something like:
|
||||
*
|
||||
* composition.Container.RegisterSingleton<IFileSystem>("media", factory => ...);
|
||||
* composition.Container.RegisterFileSystem<IMediaFileSystem, MediaFileSystem>(
|
||||
* factory => new PhysicalFileSystem("~/somewhere"));
|
||||
*
|
||||
* where the ... part returns the new underlying filesystem, as an IFileSystem.
|
||||
* return whatever supporting filesystem you like.
|
||||
*
|
||||
*
|
||||
* HOW TO IMPLEMENT MY OWN FILESYSTEM
|
||||
* ----------------------------------
|
||||
*
|
||||
* Declare your filesystem interface:
|
||||
*
|
||||
* public interface IMyFileSystem : IFileSystem
|
||||
* { }
|
||||
*
|
||||
* Create your filesystem class:
|
||||
*
|
||||
* [FileSystem("my")]
|
||||
* public class MyFileSystem : FileSystemWrapper, IFormsFileSystem
|
||||
* public class MyFileSystem : FileSystemWrapper
|
||||
* {
|
||||
* public FormsFileSystem(IFileSystem innerFileSystem)
|
||||
* public MyFileSystem(IFileSystem innerFileSystem)
|
||||
* : base(innerFileSystem)
|
||||
* { }
|
||||
* }
|
||||
*
|
||||
* Register both the underlying filesystem, and your filesystem, in a component:
|
||||
* Note that the ctor parameter MUST be named innerFileSystem. fixme oh yea?
|
||||
* The ctor can have more parameters that will be resolved by the container.
|
||||
*
|
||||
* composition.Container.RegisterSingleton<IFileSystem>("my", factory => ...);
|
||||
* composition.Container.RegisterSingleton<IMyFileSystem>(factory =>
|
||||
* factory.GetInstance<FileSystems>().GetFileSystem<MyFileSystem>();
|
||||
* Register your filesystem, in a component:
|
||||
*
|
||||
* composition.Container.RegisterFileSystem<MyFileSystem>(
|
||||
* factory => new PhysicalFileSystem("~/my"));
|
||||
*
|
||||
* And that's it, you can inject MyFileSystem wherever it's needed.
|
||||
*
|
||||
*
|
||||
* You can also declare a filesystem interface:
|
||||
*
|
||||
* public interface IMyFileSystem : IFileSystem
|
||||
* { }
|
||||
*
|
||||
* Make the class implement the interface, then
|
||||
* register your filesystem, in a component:
|
||||
*
|
||||
* composition.Container.RegisterFileSystem<IMyFileSystem, MyFileSystem>(
|
||||
* factory => new PhysicalFileSystem("~/my"));
|
||||
*
|
||||
* And that's it, you can inject IMyFileSystem wherever it's needed.
|
||||
*
|
||||
@@ -53,14 +65,6 @@ namespace Umbraco.Core.Composing.Composers
|
||||
* compared to creating your own physical filesystem, ensures that your filesystem
|
||||
* would participate into such transactions.
|
||||
*
|
||||
* Also note that in order for things to work correctly, all filesystems should
|
||||
* be instantiated before shadowing - so if registering a new filesystem in a
|
||||
* component, it's a good idea to initialize it. This would be enough (in the
|
||||
* component):
|
||||
*
|
||||
* public void Initialize(IMyFileSystem fs)
|
||||
* { }
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -70,34 +74,19 @@ namespace Umbraco.Core.Composing.Composers
|
||||
// it needs to be registered (not only the interface) because it provides additional
|
||||
// functionality eg for scoping, and is injected in the scope provider - whereas the
|
||||
// interface is really for end-users to get access to filesystems.
|
||||
//container.RegisterSingleton<FileSystems>();
|
||||
container.RegisterSingleton(factory => factory.CreateInstance<FileSystems>(new { container} ));
|
||||
|
||||
// register IFileSystems, which gives access too all filesystems
|
||||
container.RegisterSingleton<IFileSystems>(factory => factory.GetInstance<FileSystems>());
|
||||
|
||||
// register IMediaFileSystem with its actual, underlying filesystem factory
|
||||
container.RegisterSingleton<IMediaFileSystem>(factory => factory.GetInstance<FileSystems>().GetFileSystem<MediaFileSystem>(MediaInnerFileSystemFactory));
|
||||
// register the scheme for media paths
|
||||
container.RegisterSingleton<IMediaPathScheme, TwoGuidsMediaPathScheme>();
|
||||
|
||||
// register the IMediaFileSystem implementation with a supporting filesystem
|
||||
container.RegisterFileSystem<IMediaFileSystem, MediaFileSystem>(
|
||||
factory => new PhysicalFileSystem("~/media"));
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
private static IFileSystem MediaInnerFileSystemFactory()
|
||||
{
|
||||
// for the time being, we still use the FileSystemProvider config file
|
||||
// but, detect if ppl are trying to use it to change the "provider"
|
||||
|
||||
var virtualRoot = "~/media";
|
||||
|
||||
var config = (FileSystemProvidersSection)ConfigurationManager.GetSection("umbracoConfiguration/FileSystemProviders");
|
||||
var p = config?.Providers["media"];
|
||||
if (p == null) return new PhysicalFileSystem(virtualRoot);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(p.Type) && p.Type != "Umbraco.Core.IO.PhysicalFileSystem, Umbraco.Core")
|
||||
throw new InvalidOperationException("Setting a provider type in FileSystemProviders.config is not supported anymore, see FileSystemsComposer for help.");
|
||||
|
||||
virtualRoot = p?.Parameters["virtualRoot"]?.Value ?? "~/media";
|
||||
return new PhysicalFileSystem(virtualRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Umbraco.Core.IO;
|
||||
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
@@ -167,6 +168,8 @@ namespace Umbraco.Core.Composing
|
||||
// more expensive to build and cache a dynamic method ctor than to simply invoke the ctor, as we do
|
||||
// here - this can be discussed
|
||||
|
||||
// TODO: we currently try the ctor with most parameters, but we could want to fall back to others
|
||||
|
||||
var ctor = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public).OrderByDescending(x => x.GetParameters().Length).FirstOrDefault();
|
||||
if (ctor == null) throw new InvalidOperationException($"Could not find a public constructor for type {type.FullName}.");
|
||||
|
||||
@@ -177,10 +180,50 @@ namespace Umbraco.Core.Composing
|
||||
{
|
||||
// no! IsInstanceOfType is not ok here
|
||||
// ReSharper disable once UseMethodIsInstanceOfType
|
||||
// fixme so we just ignore the names?
|
||||
var arg = args?.Values.FirstOrDefault(a => parameter.ParameterType.IsAssignableFrom(a.GetType()));
|
||||
ctorArgs[i++] = arg ?? container.GetInstance(parameter.ParameterType);
|
||||
}
|
||||
return ctor.Invoke(ctorArgs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a filesystem.
|
||||
/// </summary>
|
||||
/// <typeparam name="TFileSystem">The type of the filesystem.</typeparam>
|
||||
/// <typeparam name="TImplementing">The implementing type.</typeparam>
|
||||
/// <param name="container">The container.</param>
|
||||
/// <param name="supportingFileSystemFactory">A factory method creating the supporting filesystem.</param>
|
||||
/// <returns>The container.</returns>
|
||||
public static IContainer RegisterFileSystem<TFileSystem, TImplementing>(this IContainer container, Func<IContainer, IFileSystem> supportingFileSystemFactory)
|
||||
where TImplementing : FileSystemWrapper, TFileSystem
|
||||
{
|
||||
container.RegisterSingleton<TFileSystem>(factory =>
|
||||
{
|
||||
var fileSystems = factory.GetInstance<FileSystems>();
|
||||
return fileSystems.GetFileSystem<TImplementing>(supportingFileSystemFactory(factory));
|
||||
});
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a filesystem.
|
||||
/// </summary>
|
||||
/// <typeparam name="TFileSystem">The type of the filesystem.</typeparam>
|
||||
/// <param name="container">The container.</param>
|
||||
/// <param name="supportingFileSystemFactory">A factory method creating the supporting filesystem.</param>
|
||||
/// <returns>The container.</returns>
|
||||
public static IContainer RegisterFileSystem<TFileSystem>(this IContainer container, Func<IContainer, IFileSystem> supportingFileSystemFactory)
|
||||
where TFileSystem : FileSystemWrapper
|
||||
{
|
||||
container.RegisterSingleton(factory =>
|
||||
{
|
||||
var fileSystems = factory.GetInstance<FileSystems>();
|
||||
return fileSystems.GetFileSystem<TFileSystem>(supportingFileSystemFactory(factory));
|
||||
});
|
||||
|
||||
return container;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Composing;
|
||||
@@ -13,7 +12,7 @@ namespace Umbraco.Core.IO
|
||||
private readonly IContainer _container;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly ConcurrentDictionary<string, Lazy<IFileSystem>> _filesystems = new ConcurrentDictionary<string, Lazy<IFileSystem>>();
|
||||
private readonly ConcurrentDictionary<Type, Lazy<IFileSystem>> _filesystems = new ConcurrentDictionary<Type, Lazy<IFileSystem>>();
|
||||
|
||||
// wrappers for shadow support
|
||||
private ShadowWrapper _macroPartialFileSystem;
|
||||
@@ -170,18 +169,17 @@ namespace Umbraco.Core.IO
|
||||
/// <para>Note that any filesystem created by this method *after* shadowing begins, will *not* be
|
||||
/// shadowing (and an exception will be thrown by the ShadowWrapper).</para>
|
||||
/// </remarks>
|
||||
public TFileSystem GetFileSystem<TFileSystem>(Func<IFileSystem> innerFileSystemFactory)
|
||||
public TFileSystem GetFileSystem<TFileSystem>(IFileSystem supporting)
|
||||
where TFileSystem : FileSystemWrapper
|
||||
{
|
||||
if (Volatile.Read(ref _wkfsInitialized) == false) EnsureWellKnownFileSystems();
|
||||
|
||||
var name = typeof(TFileSystem).FullName;
|
||||
if (name == null) throw new Exception("panic!");
|
||||
|
||||
return (TFileSystem) _filesystems.GetOrAdd(name, _ => new Lazy<IFileSystem>(() =>
|
||||
return (TFileSystem) _filesystems.GetOrAdd(typeof(TFileSystem), _ => new Lazy<IFileSystem>(() =>
|
||||
{
|
||||
var innerFileSystem = innerFileSystemFactory();
|
||||
var shadowWrapper = CreateShadowWrapper(innerFileSystem, "typed/" + name);
|
||||
var name = typeof(TFileSystem).FullName;
|
||||
if (name == null) throw new Exception("panic!");
|
||||
|
||||
var shadowWrapper = CreateShadowWrapper(supporting, "typed/" + name);
|
||||
return _container.CreateInstance<TFileSystem>(new { innerFileSystem = shadowWrapper });
|
||||
})).Value;
|
||||
}
|
||||
@@ -194,19 +192,6 @@ namespace Umbraco.Core.IO
|
||||
// shadowing is thread-safe, but entering and exiting shadow mode is not, and there is only one
|
||||
// global shadow for the entire application, so great care should be taken to ensure that the
|
||||
// application is *not* doing anything else when using a shadow.
|
||||
// shadow applies to well-known filesystems *only* - at the moment, any other filesystem that would
|
||||
// be created directly (via ctor) or via GetFileSystem<T> is *not* shadowed.
|
||||
|
||||
// shadow must be enabled in an app event handler before anything else ie before any filesystem
|
||||
// is actually created and used - after, it is too late - enabling shadow has a negligible perfs
|
||||
// impact.
|
||||
// NO! by the time an app event handler is instantiated it is already too late, see note in ctor.
|
||||
//internal void EnableShadow()
|
||||
//{
|
||||
// if (_mvcViewsFileSystem != null) // test one of the fs...
|
||||
// throw new InvalidOperationException("Cannot enable shadow once filesystems have been created.");
|
||||
// _shadowEnabled = true;
|
||||
//}
|
||||
|
||||
internal ICompletable Shadow(Guid id)
|
||||
{
|
||||
|
||||
@@ -7,35 +7,27 @@ namespace Umbraco.Core.IO
|
||||
/// </summary>
|
||||
public interface IMediaPathScheme
|
||||
{
|
||||
// fixme
|
||||
// to anyone finding this code: YES the Initialize() method is CompletelyBroken™ (temporal whatever)
|
||||
// but at the moment, the media filesystem wants a scheme which wants a filesystem, and it's all
|
||||
// convoluted due to how filesystems are managed in FileSystems - clear that part first!
|
||||
|
||||
/// <summary>
|
||||
/// Initialize.
|
||||
/// </summary>
|
||||
void Initialize(IFileSystem filesystem);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a media file path.
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">The media filesystem.</param>
|
||||
/// <param name="itemGuid">The (content, media) item unique identifier.</param>
|
||||
/// <param name="propertyGuid">The property type unique identifier.</param>
|
||||
/// <param name="filename">The file name.</param>
|
||||
/// <param name="previous">A previous filename.</param>
|
||||
/// <returns>The filesystem-relative complete file path.</returns>
|
||||
string GetFilePath(Guid itemGuid, Guid propertyGuid, string filename, string previous = null);
|
||||
string GetFilePath(IMediaFileSystem fileSystem, Guid itemGuid, Guid propertyGuid, string filename, string previous = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the directory that can be deleted when the file is deleted.
|
||||
/// </summary>
|
||||
/// <param name="fileSystem">The media filesystem.</param>
|
||||
/// <param name="filepath">The filesystem-relative path of the file.</param>
|
||||
/// <returns>The filesystem-relative path of the directory.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The directory, and anything below it, will be deleted.</para>
|
||||
/// <para>Can return null (or empty) when no directory should be deleted.</para>
|
||||
/// </remarks>
|
||||
string GetDeleteDirectory(string filepath);
|
||||
string GetDeleteDirectory(IMediaFileSystem fileSystem, string filepath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Logging;
|
||||
@@ -17,24 +19,21 @@ namespace Umbraco.Core.IO
|
||||
/// </summary>
|
||||
public class MediaFileSystem : FileSystemWrapper, IMediaFileSystem
|
||||
{
|
||||
private readonly IMediaPathScheme _mediaPathScheme;
|
||||
private readonly IContentSection _contentConfig;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MediaFileSystem"/> class.
|
||||
/// </summary>
|
||||
public MediaFileSystem(IFileSystem innerFileSystem)
|
||||
public MediaFileSystem(IFileSystem innerFileSystem, IContentSection contentConfig, IMediaPathScheme mediaPathScheme, ILogger logger)
|
||||
: base(innerFileSystem)
|
||||
{
|
||||
ContentConfig = Current.Container.GetInstance<IContentSection>();
|
||||
Logger = Current.Container.GetInstance<ILogger>();
|
||||
MediaPathScheme = Current.Container.GetInstance<IMediaPathScheme>();
|
||||
MediaPathScheme.Initialize(this);
|
||||
_contentConfig = contentConfig;
|
||||
_mediaPathScheme = mediaPathScheme;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
private IMediaPathScheme MediaPathScheme { get; }
|
||||
|
||||
private IContentSection ContentConfig { get; }
|
||||
|
||||
private ILogger Logger { get; }
|
||||
|
||||
/// <inheritoc />
|
||||
public void DeleteMediaFiles(IEnumerable<string> files)
|
||||
{
|
||||
@@ -51,13 +50,13 @@ namespace Umbraco.Core.IO
|
||||
if (FileExists(file) == false) return;
|
||||
DeleteFile(file);
|
||||
|
||||
var directory = MediaPathScheme.GetDeleteDirectory(file);
|
||||
var directory = _mediaPathScheme.GetDeleteDirectory(this, file);
|
||||
if (!directory.IsNullOrWhiteSpace())
|
||||
DeleteDirectory(directory, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error<MediaFileSystem>(e, "Failed to delete media file '{File}'.", file);
|
||||
_logger.Error<MediaFileSystem>(e, "Failed to delete media file '{File}'.", file);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -71,7 +70,7 @@ namespace Umbraco.Core.IO
|
||||
if (filename == null) throw new ArgumentException("Cannot become a safe filename.", nameof(filename));
|
||||
filename = IOHelper.SafeFileName(filename.ToLowerInvariant());
|
||||
|
||||
return MediaPathScheme.GetFilePath(cuid, puid, filename);
|
||||
return _mediaPathScheme.GetFilePath(this, cuid, puid, filename);
|
||||
}
|
||||
|
||||
/// <inheritoc />
|
||||
@@ -81,7 +80,7 @@ namespace Umbraco.Core.IO
|
||||
if (filename == null) throw new ArgumentException("Cannot become a safe filename.", nameof(filename));
|
||||
filename = IOHelper.SafeFileName(filename.ToLowerInvariant());
|
||||
|
||||
return MediaPathScheme.GetFilePath(cuid, puid, filename, prevpath);
|
||||
return _mediaPathScheme.GetFilePath(this, cuid, puid, filename, prevpath);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -124,6 +123,6 @@ namespace Umbraco.Core.IO
|
||||
return filepath;
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,7 @@ namespace Umbraco.Core.IO.MediaPathSchemes
|
||||
public class CombinedGuidsMediaPathScheme : IMediaPathScheme
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public void Initialize(IFileSystem filesystem)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetFilePath(Guid itemGuid, Guid propertyGuid, string filename, string previous = null)
|
||||
public string GetFilePath(IMediaFileSystem fileSystem, Guid itemGuid, Guid propertyGuid, string filename, string previous = null)
|
||||
{
|
||||
// assumes that cuid and puid keys can be trusted - and that a single property type
|
||||
// for a single content cannot store two different files with the same name
|
||||
@@ -25,7 +21,7 @@ namespace Umbraco.Core.IO.MediaPathSchemes
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetDeleteDirectory(string filepath)
|
||||
public string GetDeleteDirectory(IMediaFileSystem fileSystem, string filepath)
|
||||
{
|
||||
return Path.GetDirectoryName(filepath);
|
||||
}
|
||||
|
||||
@@ -17,18 +17,11 @@ namespace Umbraco.Core.IO.MediaPathSchemes
|
||||
public class OriginalMediaPathScheme : IMediaPathScheme
|
||||
{
|
||||
private readonly object _folderCounterLock = new object();
|
||||
private IFileSystem _filesystem;
|
||||
private long _folderCounter;
|
||||
private bool _folderCounterInitialized;
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Initialize(IFileSystem filesystem)
|
||||
{
|
||||
_filesystem = filesystem;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetFilePath(Guid itemGuid, Guid propertyGuid, string filename, string previous = null)
|
||||
public string GetFilePath(IMediaFileSystem fileSystem, Guid itemGuid, Guid propertyGuid, string filename, string previous = null)
|
||||
{
|
||||
string directory;
|
||||
if (previous != null)
|
||||
@@ -41,11 +34,11 @@ namespace Umbraco.Core.IO.MediaPathSchemes
|
||||
var pos = previous.IndexOf(sep, StringComparison.Ordinal);
|
||||
var s = pos > 0 ? previous.Substring(0, pos) : null;
|
||||
|
||||
directory = pos > 0 && int.TryParse(s, out _) ? s : GetNextDirectory();
|
||||
directory = pos > 0 && int.TryParse(s, out _) ? s : GetNextDirectory(fileSystem);
|
||||
}
|
||||
else
|
||||
{
|
||||
directory = GetNextDirectory();
|
||||
directory = GetNextDirectory(fileSystem);
|
||||
}
|
||||
|
||||
if (directory == null)
|
||||
@@ -57,25 +50,25 @@ namespace Umbraco.Core.IO.MediaPathSchemes
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetDeleteDirectory(string filepath)
|
||||
public string GetDeleteDirectory(IMediaFileSystem fileSystem, string filepath)
|
||||
{
|
||||
return Path.GetDirectoryName(filepath);
|
||||
}
|
||||
|
||||
private string GetNextDirectory()
|
||||
private string GetNextDirectory(IFileSystem fileSystem)
|
||||
{
|
||||
EnsureFolderCounterIsInitialized();
|
||||
EnsureFolderCounterIsInitialized(fileSystem);
|
||||
return Interlocked.Increment(ref _folderCounter).ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
private void EnsureFolderCounterIsInitialized()
|
||||
private void EnsureFolderCounterIsInitialized(IFileSystem fileSystem)
|
||||
{
|
||||
lock (_folderCounterLock)
|
||||
{
|
||||
if (_folderCounterInitialized) return;
|
||||
|
||||
_folderCounter = 1000; // seed
|
||||
var directories = _filesystem.GetDirectories("");
|
||||
var directories = fileSystem.GetDirectories("");
|
||||
foreach (var directory in directories)
|
||||
{
|
||||
if (long.TryParse(directory, out var folderNumber) && folderNumber > _folderCounter)
|
||||
|
||||
@@ -12,17 +12,13 @@ namespace Umbraco.Core.IO.MediaPathSchemes
|
||||
public class TwoGuidsMediaPathScheme : IMediaPathScheme
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public void Initialize(IFileSystem filesystem)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetFilePath(Guid itemGuid, Guid propertyGuid, string filename, string previous = null)
|
||||
public string GetFilePath(IMediaFileSystem fileSystem, Guid itemGuid, Guid propertyGuid, string filename, string previous = null)
|
||||
{
|
||||
return Path.Combine(itemGuid.ToString("N"), propertyGuid.ToString("N"), filename).Replace('\\', '/');
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetDeleteDirectory(string filepath)
|
||||
public string GetDeleteDirectory(IMediaFileSystem fileSystem, string filepath)
|
||||
{
|
||||
return Path.GetDirectoryName(filepath);
|
||||
}
|
||||
|
||||
@@ -107,8 +107,6 @@ namespace Umbraco.Core.Runtime
|
||||
|
||||
// by default, register a noop factory
|
||||
composition.Container.RegisterSingleton<IPublishedModelFactory, NoopPublishedModelFactory>();
|
||||
|
||||
composition.Container.RegisterSingleton<IMediaPathScheme, TwoGuidsMediaPathScheme>();
|
||||
}
|
||||
|
||||
internal void Initialize(IEnumerable<Profile> mapperProfiles)
|
||||
|
||||
@@ -398,7 +398,7 @@ namespace Umbraco.Tests.IO
|
||||
|
||||
var container = Mock.Of<IContainer>();
|
||||
var fileSystems = new FileSystems(container, logger) { IsScoped = () => scopedFileSystems };
|
||||
var fs = fileSystems.GetFileSystem<FS>(() => phy);
|
||||
var fs = fileSystems.GetFileSystem<FS>(phy);
|
||||
var sw = (ShadowWrapper) fs.InnerFileSystem;
|
||||
|
||||
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
|
||||
@@ -491,7 +491,7 @@ namespace Umbraco.Tests.IO
|
||||
|
||||
var container = Mock.Of<IContainer>();
|
||||
var fileSystems = new FileSystems(container, logger) { IsScoped = () => scopedFileSystems };
|
||||
var fs = fileSystems.GetFileSystem<FS>(() => phy);
|
||||
var fs = fileSystems.GetFileSystem<FS>( phy);
|
||||
var sw = (ShadowWrapper) fs.InnerFileSystem;
|
||||
|
||||
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
|
||||
@@ -544,7 +544,7 @@ namespace Umbraco.Tests.IO
|
||||
|
||||
var container = Mock.Of<IContainer>();
|
||||
var fileSystems = new FileSystems(container, logger) { IsScoped = () => scopedFileSystems };
|
||||
var fs = fileSystems.GetFileSystem<FS>(() => phy);
|
||||
var fs = fileSystems.GetFileSystem<FS>( phy);
|
||||
var sw = (ShadowWrapper)fs.InnerFileSystem;
|
||||
|
||||
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes("foo")))
|
||||
|
||||
@@ -29,7 +29,12 @@ namespace Umbraco.Tests.Models
|
||||
|
||||
// reference, so static ctor runs, so event handlers register
|
||||
// and then, this will reset the width, height... because the file does not exist, of course ;-(
|
||||
var ignored = new FileUploadPropertyEditor(Mock.Of<ILogger>(), new MediaFileSystem(Mock.Of<IFileSystem>()), Mock.Of<IContentSection>());
|
||||
var logger = Mock.Of<ILogger>();
|
||||
var scheme = Mock.Of<IMediaPathScheme>();
|
||||
var config = Mock.Of<IContentSection>();
|
||||
|
||||
var mediaFileSystem = new MediaFileSystem(Mock.Of<IFileSystem>(), config, scheme, logger);
|
||||
var ignored = new FileUploadPropertyEditor(Mock.Of<ILogger>(), mediaFileSystem, config);
|
||||
|
||||
var media = MockedMedia.CreateMediaImage(mediaType, -1);
|
||||
media.WriterId = -1; // else it's zero and that's not a user and it breaks the tests
|
||||
|
||||
@@ -70,10 +70,11 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
|
||||
container.RegisterCollectionBuilder<PropertyValueConverterCollectionBuilder>();
|
||||
|
||||
Current.Container.RegisterSingleton<ILogger>(f => Mock.Of<ILogger>());
|
||||
Current.Container.RegisterSingleton<IContentSection>(f => Mock.Of<IContentSection>());
|
||||
Current.Container.RegisterSingleton<IMediaPathScheme>(f => Mock.Of<IMediaPathScheme>());
|
||||
var mediaFileSystem = new MediaFileSystem(Mock.Of<IFileSystem>());
|
||||
var logger = Mock.Of<ILogger>();
|
||||
var scheme = Mock.Of<IMediaPathScheme>();
|
||||
var config = Mock.Of<IContentSection>();
|
||||
|
||||
var mediaFileSystem = new MediaFileSystem(Mock.Of<IFileSystem>(), config, scheme, logger);
|
||||
|
||||
var dataTypeService = new TestObjects.TestDataTypeService(
|
||||
new DataType(new ImageCropperPropertyEditor(Mock.Of<ILogger>(), mediaFileSystem, Mock.Of<IContentSection>(), Mock.Of<IDataTypeService>())) { Id = 1 });
|
||||
|
||||
@@ -117,7 +117,10 @@ namespace Umbraco.Tests.TestHelpers
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
if (eventMessagesFactory == null) throw new ArgumentNullException(nameof(eventMessagesFactory));
|
||||
|
||||
var mediaFileSystem = new MediaFileSystem(Mock.Of<IFileSystem>());
|
||||
var scheme = Mock.Of<IMediaPathScheme>();
|
||||
var config = Mock.Of<IContentSection>();
|
||||
|
||||
var mediaFileSystem = new MediaFileSystem(Mock.Of<IFileSystem>(), config, scheme, logger);
|
||||
|
||||
var externalLoginService = GetLazyService<IExternalLoginService>(container, c => new ExternalLoginService(scopeProvider, logger, eventMessagesFactory, GetRepo<IExternalLoginRepository>(c)));
|
||||
var publicAccessService = GetLazyService<IPublicAccessService>(container, c => new PublicAccessService(scopeProvider, logger, eventMessagesFactory, GetRepo<IPublicAccessRepository>(c)));
|
||||
|
||||
@@ -295,7 +295,13 @@ namespace Umbraco.Tests.Testing
|
||||
|
||||
// register filesystems
|
||||
Container.RegisterSingleton(factory => TestObjects.GetFileSystemsMock());
|
||||
Container.RegisterSingleton<IMediaFileSystem>(factory => new MediaFileSystem(Mock.Of<IFileSystem>()));
|
||||
|
||||
var logger = Mock.Of<ILogger>();
|
||||
var scheme = Mock.Of<IMediaPathScheme>();
|
||||
var config = Mock.Of<IContentSection>();
|
||||
|
||||
var mediaFileSystem = new MediaFileSystem(Mock.Of<IFileSystem>(), config, scheme, logger);
|
||||
Container.RegisterSingleton<IMediaFileSystem>(factory => mediaFileSystem);
|
||||
|
||||
// no factory (noop)
|
||||
Container.RegisterSingleton<IPublishedModelFactory, NoopPublishedModelFactory>();
|
||||
|
||||
Reference in New Issue
Block a user