mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 11:44:58 +08:00
Add Unit Tests for AssemblyProbingFolder
--HG-- branch : dev rename : src/Orchard/FileSystems/Dependencies/IAssenblyProbyFolder.cs => src/Orchard/FileSystems/Dependencies/IAssemblyProbingFolder.cs
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
using NUnit.Framework;
|
||||
using Orchard.FileSystems.Dependencies;
|
||||
using Orchard.Tests.Stubs;
|
||||
|
||||
namespace Orchard.Tests.FileSystems.Dependencies {
|
||||
[TestFixture]
|
||||
public class AssemblyProbingFolderTests {
|
||||
|
||||
[Test]
|
||||
public void FolderShouldBeEmptyByDefault() {
|
||||
var clock = new StubClock();
|
||||
var appDataFolder = new StubAppDataFolder(clock);
|
||||
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder);
|
||||
|
||||
Assert.That(dependenciesFolder.AssemblyExists("foo"), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LoadAssemblyShouldNotThrowIfAssemblyNotFound() {
|
||||
var clock = new StubClock();
|
||||
var appDataFolder = new StubAppDataFolder(clock);
|
||||
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder);
|
||||
|
||||
Assert.That(dependenciesFolder.LoadAssembly("foo"), Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetAssemblyDateTimeUtcShouldThrowIfAssemblyNotFound() {
|
||||
var clock = new StubClock();
|
||||
var appDataFolder = new StubAppDataFolder(clock);
|
||||
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder);
|
||||
|
||||
Assert.That(() => dependenciesFolder.GetAssemblyDateTimeUtc("foo"), Throws.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeleteAssemblyShouldNotThrowIfAssemblyNotFound() {
|
||||
var clock = new StubClock();
|
||||
var appDataFolder = new StubAppDataFolder(clock);
|
||||
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder);
|
||||
|
||||
Assert.DoesNotThrow(() => dependenciesFolder.DeleteAssembly("foo"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StoreAssemblyShouldCopyFile() {
|
||||
var clock = new StubClock();
|
||||
var appDataFolder = new StubAppDataFolder(clock);
|
||||
|
||||
var assembly = GetType().Assembly;
|
||||
var name = assembly.GetName().Name;
|
||||
|
||||
{
|
||||
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder);
|
||||
dependenciesFolder.StoreAssembly(name, assembly.Location);
|
||||
}
|
||||
|
||||
{
|
||||
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder);
|
||||
Assert.That(dependenciesFolder.AssemblyExists(name), Is.True);
|
||||
Assert.That(dependenciesFolder.LoadAssembly(name), Is.SameAs(GetType().Assembly));
|
||||
Assert.DoesNotThrow(() => dependenciesFolder.DeleteAssembly(name));
|
||||
Assert.That(dependenciesFolder.LoadAssembly(name), Is.Null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -29,8 +29,8 @@ namespace Orchard.Tests.FileSystems.Dependencies {
|
||||
LoaderName = "test",
|
||||
VirtualPath = "~/bin"
|
||||
};
|
||||
|
||||
dependenciesFolder.StoreDescriptors(new [] { d });
|
||||
|
||||
dependenciesFolder.StoreDescriptors(new[] { d });
|
||||
var e = dependenciesFolder.LoadDescriptors();
|
||||
Assert.That(e, Has.Count.EqualTo(1));
|
||||
Assert.That(e.First().Name, Is.EqualTo("name"));
|
||||
@@ -113,7 +113,7 @@ namespace Orchard.Tests.FileSystems.Dependencies {
|
||||
};
|
||||
|
||||
dependenciesFolder.StoreDescriptors(new[] { d1, d2 });
|
||||
|
||||
|
||||
// Create a new instance over the same appDataFolder
|
||||
var dependenciesFolder2 = new DefaultDependenciesFolder(new StubCacheManager(), appDataFolder);
|
||||
|
||||
|
@@ -197,6 +197,7 @@
|
||||
<Compile Include="Environment\OrchardStarterTests.cs" />
|
||||
<Compile Include="Environment\ShellBuilders\DefaultShellContainerFactoryTests.cs" />
|
||||
<Compile Include="Environment\ShellBuilders\DefaultShellContextFactoryTests.cs" />
|
||||
<Compile Include="FileSystems\Dependencies\AssemblyProbingFolderTests.cs" />
|
||||
<Compile Include="FileSystems\Dependencies\DependenciesFolderTests.cs" />
|
||||
<Compile Include="Localization\CultureManagerTests.cs" />
|
||||
<Compile Include="Mvc\Routes\ShellRouteTests.cs" />
|
||||
|
@@ -45,7 +45,7 @@ namespace Orchard.Tests.Stubs {
|
||||
}
|
||||
|
||||
public void CreateFile(string path, string content) {
|
||||
using(var stream = CreateFile(path)) {
|
||||
using (var stream = CreateFile(path)) {
|
||||
using (var writer = new StreamWriter(stream)) {
|
||||
writer.Write(content);
|
||||
}
|
||||
@@ -68,8 +68,29 @@ namespace Orchard.Tests.Stubs {
|
||||
return _fileSystem.OpenFile(path);
|
||||
}
|
||||
|
||||
public void StoreFile(string sourceFileName, string destinationPath) {
|
||||
using (var inputStream = File.OpenRead(sourceFileName)) {
|
||||
using (var outputStream = _fileSystem.CreateFile(destinationPath)) {
|
||||
byte[] buffer = new byte[1024];
|
||||
for (; ; ) {
|
||||
var count = inputStream.Read(buffer, 0, buffer.Length);
|
||||
if (count == 0)
|
||||
break;
|
||||
outputStream.Write(buffer, 0, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteFile(string path) {
|
||||
throw new NotImplementedException();
|
||||
_fileSystem.DeleteFile(path);
|
||||
}
|
||||
|
||||
public DateTime GetFileLastWriteTimeUtc(string path) {
|
||||
var entry = _fileSystem.GetFileEntry(path);
|
||||
if (entry == null)
|
||||
throw new ArgumentException();
|
||||
return entry.LastWriteTimeUtc;
|
||||
}
|
||||
|
||||
public void CreateDirectory(string path) {
|
||||
@@ -88,7 +109,7 @@ namespace Orchard.Tests.Stubs {
|
||||
var entry = _fileSystem.GetFileEntry(path);
|
||||
if (entry == null)
|
||||
throw new InvalidOperationException();
|
||||
return entry.LastWriteTime;
|
||||
return entry.LastWriteTimeUtc;
|
||||
}
|
||||
}
|
||||
}
|
@@ -68,12 +68,12 @@ namespace Orchard.Tests.Stubs {
|
||||
|
||||
public FileEntry(IClock clock) {
|
||||
_clock = clock;
|
||||
LastWriteTime = _clock.UtcNow;
|
||||
LastWriteTimeUtc = _clock.UtcNow;
|
||||
Content = new List<byte>();
|
||||
}
|
||||
|
||||
public List<byte> Content { get; private set; }
|
||||
public DateTime LastWriteTime { get; set; }
|
||||
public DateTime LastWriteTimeUtc { get; set; }
|
||||
}
|
||||
|
||||
public class Token : IVolatileToken {
|
||||
@@ -178,7 +178,7 @@ namespace Orchard.Tests.Stubs {
|
||||
var wrapper = new ArrayWrapper<byte>(buffer, offset, count);
|
||||
_entry.Content.AddRange(wrapper);
|
||||
|
||||
_entry.LastWriteTime = _clock.UtcNow;
|
||||
_entry.LastWriteTimeUtc = _clock.UtcNow;
|
||||
if (_token != null)
|
||||
_token.OnChange();
|
||||
_position += count;
|
||||
@@ -368,5 +368,20 @@ namespace Orchard.Tests.Stubs {
|
||||
|
||||
return new FileEntryReadStream(entry, _clock);
|
||||
}
|
||||
|
||||
public void DeleteFile(string path) {
|
||||
var directoryName = Path.GetDirectoryName(path);
|
||||
var fileName = Path.GetFileName(path);
|
||||
|
||||
var directory = GetDirectoryEntry(directoryName);
|
||||
if (directory == null)
|
||||
return;
|
||||
|
||||
var entry = directory.GetEntry(fileName);
|
||||
if (entry == null)
|
||||
return;
|
||||
|
||||
directory.Entries.Remove(entry);
|
||||
}
|
||||
}
|
||||
}
|
@@ -42,7 +42,7 @@ namespace Orchard.Environment.Extensions {
|
||||
var deletedDependencies = existingDependencies.Where(e => !extensions.Any(e2 => e2.Name == e.Name)).ToList();
|
||||
var newExtensions = extensions.Except(sameExtensions).ToList();
|
||||
|
||||
var ctx = new ExtensionLoadingContext { DependenciesFolder = _dependenciesFolder };
|
||||
var ctx = new ExtensionLoadingContext();
|
||||
|
||||
// Notify all loaders about extensions removed from the web site
|
||||
foreach (var dependency in deletedDependencies) {
|
||||
@@ -123,19 +123,12 @@ namespace Orchard.Environment.Extensions {
|
||||
|
||||
private void ProcessContextCommands(ExtensionLoadingContext ctx) {
|
||||
Logger.Information("Executing list of operations needed for loading extensions...");
|
||||
foreach (var fileName in ctx.FilesToDelete) {
|
||||
Logger.Information("Deleting file \"{0}\"", fileName);
|
||||
File.Delete(fileName);
|
||||
foreach (var action in ctx.DeleteActions) {
|
||||
action();
|
||||
}
|
||||
foreach (var entry in ctx.FilesToCopy) {
|
||||
Logger.Information("Copying file from \"{0}\" to \"{1}\"", entry.Key, entry.Value);
|
||||
MakeDestinationFileNameAvailable(entry.Value);
|
||||
File.Copy(entry.Key, entry.Value);
|
||||
}
|
||||
foreach (var entry in ctx.FilesToRename) {
|
||||
Logger.Information("Moving file from \"{0}\" to \"{1}\"", entry.Key, entry.Value);
|
||||
MakeDestinationFileNameAvailable(entry.Value);
|
||||
File.Move(entry.Key, entry.Value);
|
||||
|
||||
foreach (var action in ctx.CopyActions) {
|
||||
action();
|
||||
}
|
||||
|
||||
if (ctx.RestartAppDomain) {
|
||||
@@ -149,39 +142,6 @@ namespace Orchard.Environment.Extensions {
|
||||
}
|
||||
}
|
||||
|
||||
private void MakeDestinationFileNameAvailable(string destinationFileName) {
|
||||
// Try deleting the destination first
|
||||
try {
|
||||
File.Delete(destinationFileName);
|
||||
} catch {
|
||||
// We land here if the file is in use, for example. Let's move on.
|
||||
}
|
||||
|
||||
// If destination doesn't exist, we are good
|
||||
if (!File.Exists(destinationFileName))
|
||||
return;
|
||||
|
||||
// Try renaming destination to a unique filename
|
||||
const string extension = "deleted";
|
||||
for (int i = 0; i < 100; i++) {
|
||||
var newExtension = (i == 0 ? extension : string.Format("{0}{1}", extension, i));
|
||||
var newFileName = Path.ChangeExtension(destinationFileName, newExtension);
|
||||
try {
|
||||
File.Delete(newFileName);
|
||||
File.Move(destinationFileName, newFileName);
|
||||
|
||||
// If successful, we are done...
|
||||
return;
|
||||
}
|
||||
catch (Exception) {
|
||||
// We need to try with another extension
|
||||
}
|
||||
}
|
||||
|
||||
// Everything failed, throw an exception
|
||||
throw new OrchardException(T("Unable to make room for file {0} in dependencies folder: too many conflicts.", destinationFileName).Text);
|
||||
}
|
||||
|
||||
public void MonitorExtensions(Action<IVolatileToken> monitor) {
|
||||
var extensions = _extensionManager.AvailableExtensions().Where(d => d.ExtensionType == "Module").ToList();
|
||||
foreach (var extension in extensions) {
|
||||
|
@@ -1,18 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using Orchard.FileSystems.Dependencies;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Orchard.Environment.Extensions {
|
||||
public class ExtensionLoadingContext {
|
||||
public ExtensionLoadingContext() {
|
||||
FilesToDelete = new HashSet<string>();
|
||||
FilesToCopy = new Dictionary<string, string>();
|
||||
FilesToRename = new Dictionary<string, string>();
|
||||
DeleteActions = new List<Action>();
|
||||
CopyActions = new List<Action>();
|
||||
}
|
||||
|
||||
public IDependenciesFolder DependenciesFolder { get; set; }
|
||||
public HashSet<string> FilesToDelete { get; set; }
|
||||
public Dictionary<string, string> FilesToCopy { get; set; }
|
||||
public Dictionary<string, string> FilesToRename { get; set; }
|
||||
public IList<Action> DeleteActions { get; set; }
|
||||
public IList<Action> CopyActions { get; set; }
|
||||
|
||||
public bool RestartAppDomain { get; set; }
|
||||
public bool ResetSiteCompilation { get; set; }
|
||||
}
|
||||
|
@@ -34,9 +34,8 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
}
|
||||
|
||||
public override void ExtensionRemoved(ExtensionLoadingContext ctx, DependencyDescriptor dependency) {
|
||||
var assemblyFileName = _assemblyProbingFolder.GetAssemblyPhysicalFileName(dependency.Name);
|
||||
if (File.Exists(assemblyFileName)) {
|
||||
ctx.FilesToDelete.Add(assemblyFileName);
|
||||
if (_assemblyProbingFolder.AssemblyExists(dependency.Name)) {
|
||||
ctx.DeleteActions.Add(() => _assemblyProbingFolder.DeleteAssembly(dependency.Name));
|
||||
|
||||
// We need to restart the appDomain if the assembly is loaded
|
||||
if (IsAssemblyLoaded(dependency.Name)) {
|
||||
@@ -48,9 +47,14 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
|
||||
public override void ExtensionActivated(ExtensionLoadingContext ctx, bool isNewExtension, ExtensionDescriptor extension) {
|
||||
string sourceFileName = _virtualPathProvider.MapPath(GetAssemblyPath(extension));
|
||||
string destinationFileName = _assemblyProbingFolder.GetAssemblyPhysicalFileName(extension.Name);
|
||||
if (FileIsNewer(sourceFileName, destinationFileName)) {
|
||||
ctx.FilesToCopy.Add(sourceFileName, destinationFileName);
|
||||
|
||||
// Copy the assembly if it doesn't exist or if it is older than the source file.
|
||||
bool copyAssembly =
|
||||
!_assemblyProbingFolder.AssemblyExists(extension.Name) ||
|
||||
File.GetLastWriteTimeUtc(sourceFileName) > _assemblyProbingFolder.GetAssemblyDateTimeUtc(extension.Name);
|
||||
|
||||
if (copyAssembly) {
|
||||
ctx.CopyActions.Add(() => _assemblyProbingFolder.StoreAssembly(extension.Name, sourceFileName));
|
||||
// We need to restart the appDomain if the assembly is loaded
|
||||
if (IsAssemblyLoaded(extension.Name)) {
|
||||
Logger.Information("Extension activated: Setting AppDomain for restart because assembly {0} is loaded", extension.Name);
|
||||
@@ -60,9 +64,9 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
}
|
||||
|
||||
public override void ExtensionDeactivated(ExtensionLoadingContext ctx, bool isNewExtension, ExtensionDescriptor extension) {
|
||||
var assemblyFileName = _assemblyProbingFolder.GetAssemblyPhysicalFileName(extension.Name);
|
||||
if (File.Exists(assemblyFileName)) {
|
||||
ctx.FilesToDelete.Add(assemblyFileName);
|
||||
if (_assemblyProbingFolder.AssemblyExists(extension.Name)) {
|
||||
ctx.DeleteActions.Add(() => _assemblyProbingFolder.DeleteAssembly(extension.Name));
|
||||
|
||||
// We need to restart the appDomain if the assembly is loaded
|
||||
if (IsAssemblyLoaded(extension.Name)) {
|
||||
Logger.Information("Extension deactivated: Setting AppDomain for restart because assembly {0} is loaded", extension.Name);
|
||||
|
@@ -27,9 +27,9 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
}
|
||||
|
||||
public override void ExtensionRemoved(ExtensionLoadingContext ctx, DependencyDescriptor dependency) {
|
||||
var assemblyFileName = _assemblyProbingFolder.GetAssemblyPhysicalFileName(dependency.Name);
|
||||
if (File.Exists(assemblyFileName)) {
|
||||
ctx.FilesToDelete.Add(assemblyFileName);
|
||||
if (_assemblyProbingFolder.AssemblyExists(dependency.Name)) {
|
||||
ctx.DeleteActions.Add(() => _assemblyProbingFolder.DeleteAssembly(dependency.Name));
|
||||
|
||||
// We need to restart the appDomain if the assembly is loaded
|
||||
if (IsAssemblyLoaded(dependency.Name)) {
|
||||
Logger.Information("Extension removed: Setting AppDomain for restart because assembly {0} is loaded", dependency.Name);
|
||||
@@ -39,9 +39,9 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
}
|
||||
|
||||
public override void ExtensionDeactivated(ExtensionLoadingContext ctx, bool isNewExtension, ExtensionDescriptor extension) {
|
||||
var assemblyFileName = _assemblyProbingFolder.GetAssemblyPhysicalFileName(extension.Name);
|
||||
if (File.Exists(assemblyFileName)) {
|
||||
ctx.FilesToDelete.Add(assemblyFileName);
|
||||
if (_assemblyProbingFolder.AssemblyExists(extension.Name)) {
|
||||
ctx.DeleteActions.Add(() => _assemblyProbingFolder.DeleteAssembly(extension.Name));
|
||||
|
||||
// We need to restart the appDomain if the assembly is loaded
|
||||
if (IsAssemblyLoaded(extension.Name)) {
|
||||
Logger.Information("Extension deactivated: Setting AppDomain for restart because assembly {0} is loaded", extension.Name);
|
||||
@@ -51,7 +51,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
}
|
||||
|
||||
public override ExtensionProbeEntry Probe(ExtensionDescriptor descriptor) {
|
||||
if (!_assemblyProbingFolder.HasAssembly(descriptor.Name))
|
||||
if (!_assemblyProbingFolder.AssemblyExists(descriptor.Name))
|
||||
return null;
|
||||
|
||||
var desc = _dependenciesFolder.GetDescriptor(descriptor.Name);
|
||||
|
@@ -25,7 +25,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
public override void ExtensionDeactivated(ExtensionLoadingContext ctx, bool isNewExtension, ExtensionDescriptor extension) {
|
||||
var assemblyPath = _virtualPathProvider.Combine("~/bin", extension.Name + ".dll");
|
||||
if (_virtualPathProvider.FileExists(assemblyPath)) {
|
||||
ctx.FilesToDelete.Add(_virtualPathProvider.MapPath(assemblyPath));
|
||||
ctx.DeleteActions.Add(() => File.Delete(_virtualPathProvider.MapPath(assemblyPath)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,9 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web.Hosting;
|
||||
using Orchard.Caching;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Logging;
|
||||
|
||||
namespace Orchard.FileSystems.AppData {
|
||||
public class AppDataFolder : IAppDataFolder {
|
||||
@@ -13,8 +16,13 @@ namespace Orchard.FileSystems.AppData {
|
||||
public AppDataFolder(IAppDataFolderRoot root, IVirtualPathMonitor virtualPathMonitor) {
|
||||
_root = root;
|
||||
_virtualPathMonitor = virtualPathMonitor;
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public string RootFolder {
|
||||
get {
|
||||
return _root.RootFolder;
|
||||
@@ -27,6 +35,40 @@ namespace Orchard.FileSystems.AppData {
|
||||
}
|
||||
}
|
||||
|
||||
private void MakeDestinationFileNameAvailable(string destinationFileName) {
|
||||
// Try deleting the destination first
|
||||
try {
|
||||
File.Delete(destinationFileName);
|
||||
}
|
||||
catch {
|
||||
// We land here if the file is in use, for example. Let's move on.
|
||||
}
|
||||
|
||||
// If destination doesn't exist, we are good
|
||||
if (!File.Exists(destinationFileName))
|
||||
return;
|
||||
|
||||
// Try renaming destination to a unique filename
|
||||
const string extension = "deleted";
|
||||
for (int i = 0; i < 100; i++) {
|
||||
var newExtension = (i == 0 ? extension : string.Format("{0}{1}", extension, i));
|
||||
var newFileName = Path.ChangeExtension(destinationFileName, newExtension);
|
||||
try {
|
||||
File.Delete(newFileName);
|
||||
File.Move(destinationFileName, newFileName);
|
||||
|
||||
// If successful, we are done...
|
||||
return;
|
||||
}
|
||||
catch (Exception) {
|
||||
// We need to try with another extension
|
||||
}
|
||||
}
|
||||
|
||||
// Everything failed, throw an exception
|
||||
throw new OrchardException(T("Unable to make room for file {0} in \"App_Data\" folder: too many conflicts.", destinationFileName).Text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combine a set of virtual paths relative to "~/App_Data" into an absolute physical path
|
||||
/// starting with "_basePath".
|
||||
@@ -72,10 +114,24 @@ namespace Orchard.FileSystems.AppData {
|
||||
return File.OpenRead(CombineToPhysicalPath(path));
|
||||
}
|
||||
|
||||
public void StoreFile(string sourceFileName, string destinationPath) {
|
||||
Logger.Information("Storing file \"{0}\" as \"{1}\" in App_Data folder", sourceFileName, destinationPath);
|
||||
|
||||
var destinationFileName = CombineToPhysicalPath(destinationPath);
|
||||
MakeDestinationFileNameAvailable(destinationFileName);
|
||||
File.Copy(sourceFileName, destinationFileName);
|
||||
}
|
||||
|
||||
public void DeleteFile(string path) {
|
||||
Logger.Information("Deleting file \"{0}\" from App_Data folder", path);
|
||||
|
||||
File.Delete(CombineToPhysicalPath(path));
|
||||
}
|
||||
|
||||
public DateTime GetFileLastWriteTimeUtc(string path) {
|
||||
return File.GetLastWriteTimeUtc(CombineToPhysicalPath(path));
|
||||
}
|
||||
|
||||
public bool FileExists(string path) {
|
||||
return File.Exists(CombineToPhysicalPath(path));
|
||||
}
|
||||
|
@@ -13,17 +13,18 @@ namespace Orchard.FileSystems.AppData {
|
||||
IEnumerable<string> ListFiles(string path);
|
||||
IEnumerable<string> ListDirectories(string path);
|
||||
|
||||
bool FileExists(string path);
|
||||
string Combine(params string[] paths);
|
||||
|
||||
bool FileExists(string path);
|
||||
void CreateFile(string path, string content);
|
||||
Stream CreateFile(string path);
|
||||
|
||||
string ReadFile(string path);
|
||||
Stream OpenFile(string path);
|
||||
|
||||
void StoreFile(string sourceFileName, string destinationPath);
|
||||
void DeleteFile(string path);
|
||||
|
||||
DateTime GetFileLastWriteTimeUtc(string path);
|
||||
|
||||
void CreateDirectory(string path);
|
||||
|
||||
IVolatileToken WhenPathChanges(string path);
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Orchard.FileSystems.AppData;
|
||||
|
||||
@@ -12,14 +11,14 @@ namespace Orchard.FileSystems.Dependencies {
|
||||
_appDataFolder = appDataFolder;
|
||||
}
|
||||
|
||||
public bool HasAssembly(string moduleName) {
|
||||
public bool AssemblyExists(string moduleName) {
|
||||
var path = PrecompiledAssemblyPath(moduleName);
|
||||
return _appDataFolder.FileExists(path);
|
||||
}
|
||||
|
||||
public DateTime GetAssemblyDateTimeUtc(string moduleName) {
|
||||
var path = PrecompiledAssemblyPath(moduleName);
|
||||
return File.GetLastWriteTimeUtc(_appDataFolder.MapPath(path));
|
||||
return _appDataFolder.GetFileLastWriteTimeUtc(path);
|
||||
}
|
||||
|
||||
public Assembly LoadAssembly(string moduleName) {
|
||||
@@ -30,8 +29,14 @@ namespace Orchard.FileSystems.Dependencies {
|
||||
return Assembly.Load(moduleName);
|
||||
}
|
||||
|
||||
public string GetAssemblyPhysicalFileName(string moduleName) {
|
||||
return _appDataFolder.MapPath(PrecompiledAssemblyPath(moduleName));
|
||||
public void DeleteAssembly(string moduleName) {
|
||||
var path = PrecompiledAssemblyPath(moduleName);
|
||||
_appDataFolder.DeleteFile(path);
|
||||
}
|
||||
|
||||
public void StoreAssembly(string moduleName, string fileName) {
|
||||
var path = PrecompiledAssemblyPath(moduleName);
|
||||
_appDataFolder.StoreFile(fileName, path);
|
||||
}
|
||||
|
||||
private string PrecompiledAssemblyPath(string moduleName) {
|
||||
|
@@ -13,7 +13,7 @@ namespace Orchard.FileSystems.Dependencies {
|
||||
/// Return "true" if the assembly corresponding to "moduleName" is
|
||||
/// present in the folder.
|
||||
/// </summary>
|
||||
bool HasAssembly(string moduleName);
|
||||
bool AssemblyExists(string moduleName);
|
||||
|
||||
/// <summary>
|
||||
/// Return the last modification date of the assembly corresponding
|
||||
@@ -29,12 +29,13 @@ namespace Orchard.FileSystems.Dependencies {
|
||||
Assembly LoadAssembly(string moduleName);
|
||||
|
||||
/// <summary>
|
||||
/// Return the physical location where to store the assembly
|
||||
/// corresponding to "moduleName". This will return a correct path
|
||||
/// even if the assembly is not currently stored in that location.
|
||||
/// This method can be used to answer the question "Where would the assembly
|
||||
/// for module "moduleName" be stored if it exsisted?"
|
||||
/// Ensure the assembly corresponding to "moduleName" is removed from the folder
|
||||
/// </summary>
|
||||
string GetAssemblyPhysicalFileName(string moduleName);
|
||||
void DeleteAssembly(string moduleName);
|
||||
|
||||
/// <summary>
|
||||
/// Store an assembly corresponding to "moduleName" from the given fileName
|
||||
/// </summary>
|
||||
void StoreAssembly(string moduleName, string fileName);
|
||||
}
|
||||
}
|
@@ -360,7 +360,7 @@
|
||||
<Compile Include="FileSystems\AppData\IAppDataFolderRoot.cs" />
|
||||
<Compile Include="FileSystems\Dependencies\DefaultAssemblyProbingFolder.cs" />
|
||||
<Compile Include="FileSystems\Dependencies\DefaultDependenciesFolder.cs" />
|
||||
<Compile Include="FileSystems\Dependencies\IAssenblyProbyFolder.cs" />
|
||||
<Compile Include="FileSystems\Dependencies\IAssemblyProbingFolder.cs" />
|
||||
<Compile Include="FileSystems\VirtualPath\DefaultVirtualPathMonitor.cs" />
|
||||
<Compile Include="FileSystems\VirtualPath\DefaultVirtualPathProvider.cs" />
|
||||
<Compile Include="FileSystems\VirtualPath\ICustomVirtualPathProvider.cs" />
|
||||
|
Reference in New Issue
Block a user