diff --git a/src/Orchard.Tests/Stubs/StubWebSiteFolder.cs b/src/Orchard.Tests/Stubs/StubWebSiteFolder.cs
index 82e0446ee..211824fea 100644
--- a/src/Orchard.Tests/Stubs/StubWebSiteFolder.cs
+++ b/src/Orchard.Tests/Stubs/StubWebSiteFolder.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -23,5 +24,9 @@ namespace Orchard.Tests.Stubs {
public IVolatileToken WhenPathChanges(string path) {
return new WebSiteFolder.Token(path);
}
+
+ public void WhenPathChanges(string path, Action action) {
+ throw new NotImplementedException();
+ }
}
}
\ No newline at end of file
diff --git a/src/Orchard/Environment/Extensions/Loaders/ReferencedExtensionLoader.cs b/src/Orchard/Environment/Extensions/Loaders/ReferencedExtensionLoader.cs
index 39b8a19f0..4ce622ef7 100644
--- a/src/Orchard/Environment/Extensions/Loaders/ReferencedExtensionLoader.cs
+++ b/src/Orchard/Environment/Extensions/Loaders/ReferencedExtensionLoader.cs
@@ -3,14 +3,20 @@ using System.Reflection;
using System.Web.Compilation;
using System.Web.Hosting;
using Orchard.Environment.Extensions.Models;
+using Orchard.FileSystems.Dependencies;
namespace Orchard.Environment.Extensions.Loaders {
///
/// Load an extension by looking through the BuildManager referenced assemblies
///
public class ReferencedExtensionLoader : IExtensionLoader {
+ private readonly IDependenciesFolder _dependenciesFolder;
public int Order { get { return 20; } }
+ public ReferencedExtensionLoader(IDependenciesFolder dependenciesFolder) {
+ _dependenciesFolder = dependenciesFolder;
+ }
+
public ExtensionEntry Load(ExtensionDescriptor descriptor) {
if (HostingEnvironment.IsHosted == false)
return null;
@@ -22,6 +28,8 @@ namespace Orchard.Environment.Extensions.Loaders {
if (assembly == null)
return null;
+ _dependenciesFolder.StoreReferencedAssembly(descriptor.Name);
+
return new ExtensionEntry {
Descriptor = descriptor,
Assembly = assembly,
diff --git a/src/Orchard/FileSystems/Dependencies/IDependenciesFolder.cs b/src/Orchard/FileSystems/Dependencies/IDependenciesFolder.cs
index 321f74e16..d3d87d60a 100644
--- a/src/Orchard/FileSystems/Dependencies/IDependenciesFolder.cs
+++ b/src/Orchard/FileSystems/Dependencies/IDependenciesFolder.cs
@@ -3,13 +3,11 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
-using System.Web.Caching;
-using System.Web.Hosting;
using System.Xml.Linq;
using Orchard.Caching;
using Orchard.Environment;
using Orchard.Environment.Extensions;
-using Orchard.Environment.Topology;
+using Orchard.FileSystems.WebSite;
namespace Orchard.FileSystems.Dependencies {
public class DependencyDescriptor {
@@ -20,21 +18,27 @@ namespace Orchard.FileSystems.Dependencies {
}
public interface IDependenciesFolder : IVolatileProvider {
- void StoreBuildProviderAssembly(string moduleName, string virtualPath, Assembly assembly);
+ void StoreReferencedAssembly(string moduleName);
void StorePrecompiledAssembly(string moduleName, string virtualPath);
+ void StoreBuildProviderAssembly(string moduleName, string virtualPath, Assembly assembly);
DependencyDescriptor GetDescriptor(string moduleName);
Assembly LoadAssembly(string assemblyName);
}
public class DefaultDependenciesFolder : IDependenciesFolder {
- private readonly string _prefix = Guid.NewGuid().ToString("n");
- private const string _basePath = "~/App_Data/Dependencies";
+ private readonly string _basePath = "~/App_Data/Dependencies";
+ private readonly ICacheManager _cacheManager;
+ private readonly IWebSiteFolder _webSiteFolder;
private readonly IVirtualPathProvider _virtualPathProvider;
private readonly IExtensionManagerEvents _events;
+ private readonly InvalidationToken _token;
- public DefaultDependenciesFolder(IVirtualPathProvider virtualPathProvider, IExtensionManagerEvents events) {
+ public DefaultDependenciesFolder(ICacheManager cacheManager, IWebSiteFolder webSiteFolder, IVirtualPathProvider virtualPathProvider, IExtensionManagerEvents events) {
+ _cacheManager = cacheManager;
+ _webSiteFolder = webSiteFolder;
_virtualPathProvider = virtualPathProvider;
_events = events;
+ _token = new InvalidationToken();
}
private string BasePath {
@@ -49,9 +53,33 @@ namespace Orchard.FileSystems.Dependencies {
}
}
- public void StoreBuildProviderAssembly(string moduleName, string virtualPath, Assembly assembly) {
- _virtualPathProvider.CreateDirectory(BasePath);
+ private IList Descriptors {
+ get {
+ return _cacheManager.Get(PersistencePath,
+ ctx => {
+ ctx.Monitor(_webSiteFolder.WhenPathChanges(ctx.Key));
+ ctx.Monitor(_token);
+ _virtualPathProvider.CreateDirectory(BasePath);
+ return ReadDependencies(ctx.Key);
+ });
+ }
+ }
+
+ public class InvalidationToken : IVolatileToken {
+ public bool IsCurrent { get; set; }
+ }
+
+ public void StoreReferencedAssembly(string moduleName) {
+ if (Descriptors.Any(d => d.ModuleName == moduleName)) {
+ // Remove the moduleName from the list of assemblies in the dependency folder
+ var newDescriptors = Descriptors.Where(d => d.ModuleName != moduleName);
+
+ WriteDependencies(PersistencePath, newDescriptors);
+ }
+ }
+
+ public void StoreBuildProviderAssembly(string moduleName, string virtualPath, Assembly assembly) {
var descriptor = new DependencyDescriptor {
ModuleName = moduleName,
IsFromBuildProvider = true,
@@ -61,21 +89,7 @@ namespace Orchard.FileSystems.Dependencies {
StoreDepencyInformation(descriptor);
-#if true
- var cacheDependency = HostingEnvironment.VirtualPathProvider.GetCacheDependency(
- virtualPath,
- new[] { virtualPath },
- DateTime.UtcNow);
-
- HostingEnvironment.Cache.Add(
- _prefix + virtualPath,
- moduleName,
- cacheDependency,
- Cache.NoAbsoluteExpiration,
- Cache.NoSlidingExpiration,
- CacheItemPriority.NotRemovable,
- (key, value, reason) => _events.ModuleChanged((string) value));
-#endif
+ _webSiteFolder.WhenPathChanges(virtualPath, () => _events.ModuleChanged(moduleName));
}
public void StorePrecompiledAssembly(string moduleName, string virtualPath) {
@@ -98,11 +112,11 @@ namespace Orchard.FileSystems.Dependencies {
}
public DependencyDescriptor GetDescriptor(string moduleName) {
- return ReadDependencies().SingleOrDefault(d => d.ModuleName == moduleName);
+ return Descriptors.SingleOrDefault(d => d.ModuleName == moduleName);
}
private bool IsNewerAssembly(string moduleName, string assemblyFileName) {
- var dependency = ReadDependencies().SingleOrDefault(d => d.ModuleName == moduleName);
+ var dependency = Descriptors.SingleOrDefault(d => d.ModuleName == moduleName);
if (dependency == null) {
return true;
}
@@ -116,7 +130,7 @@ namespace Orchard.FileSystems.Dependencies {
}
private void StoreDepencyInformation(DependencyDescriptor descriptor) {
- var dependencies = ReadDependencies().ToList();
+ var dependencies = Descriptors.ToList();
int index = dependencies.FindIndex(d => d.ModuleName == descriptor.ModuleName);
if (index < 0) {
dependencies.Add(descriptor);
@@ -125,13 +139,13 @@ namespace Orchard.FileSystems.Dependencies {
dependencies[index] = descriptor;
}
- WriteDependencies(dependencies);
+ WriteDependencies(PersistencePath, dependencies);
}
public Assembly LoadAssembly(string assemblyName) {
_virtualPathProvider.CreateDirectory(BasePath);
- var dependency = ReadDependencies().SingleOrDefault(d => d.ModuleName == assemblyName);
+ var dependency = Descriptors.SingleOrDefault(d => d.ModuleName == assemblyName);
if (dependency == null)
return null;
@@ -141,11 +155,13 @@ namespace Orchard.FileSystems.Dependencies {
return Assembly.Load(Path.GetFileNameWithoutExtension(dependency.FileName));
}
- private IEnumerable ReadDependencies() {
- if (!_virtualPathProvider.FileExists(PersistencePath))
+ private IEnumerable ReadDependencies(string persistancePath) {
+ Func ns = (name => XName.Get(name));
+
+ if (!_virtualPathProvider.FileExists(persistancePath))
return Enumerable.Empty();
- using (var stream = _virtualPathProvider.OpenFile(PersistencePath)) {
+ using (var stream = _virtualPathProvider.OpenFile(persistancePath)) {
XDocument document = XDocument.Load(stream);
return document
.Elements(ns("Dependencies"))
@@ -160,7 +176,9 @@ namespace Orchard.FileSystems.Dependencies {
}
}
- private void WriteDependencies(IEnumerable dependencies) {
+ private void WriteDependencies(string persistancePath, IEnumerable dependencies) {
+ Func ns = (name => XName.Get(name));
+
var document = new XDocument();
document.Add(new XElement(ns("Dependencies")));
var elements = dependencies.Select(d => new XElement("Dependency",
@@ -170,13 +188,12 @@ namespace Orchard.FileSystems.Dependencies {
new XElement(ns("FileName"), d.FileName)));
document.Root.Add(elements);
- using (var stream = _virtualPathProvider.CreateText(PersistencePath)) {
+ using (var stream = _virtualPathProvider.CreateText(persistancePath)) {
document.Save(stream, SaveOptions.None);
}
- }
- private static XName ns(string name) {
- return XName.Get(name/*, "http://schemas.microsoft.com/developer/msbuild/2003"*/);
+ // Ensure cache is invalidated right away, not waiting for file change notification to happen
+ _token.IsCurrent = false;
}
}
}
diff --git a/src/Orchard/FileSystems/WebSite/IWebSiteFolder.cs b/src/Orchard/FileSystems/WebSite/IWebSiteFolder.cs
index a7dc73925..8836d2009 100644
--- a/src/Orchard/FileSystems/WebSite/IWebSiteFolder.cs
+++ b/src/Orchard/FileSystems/WebSite/IWebSiteFolder.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using Orchard.Caching;
namespace Orchard.FileSystems.WebSite {
@@ -7,5 +8,6 @@ namespace Orchard.FileSystems.WebSite {
string ReadFile(string path);
IVolatileToken WhenPathChanges(string path);
+ void WhenPathChanges(string path, Action action);
}
}
\ No newline at end of file
diff --git a/src/Orchard/FileSystems/WebSite/WebSiteFolder.cs b/src/Orchard/FileSystems/WebSite/WebSiteFolder.cs
index d82eec4f9..d5b2ddd4b 100644
--- a/src/Orchard/FileSystems/WebSite/WebSiteFolder.cs
+++ b/src/Orchard/FileSystems/WebSite/WebSiteFolder.cs
@@ -49,6 +49,10 @@ namespace Orchard.FileSystems.WebSite {
return token;
}
+ public void WhenPathChanges(string virtualPath, Action action) {
+ BindSignal(virtualPath, (key, value, reason) => action());
+ }
+
private Token BindToken(string virtualPath) {
lock (_tokens) {
Weak weak;
@@ -80,6 +84,11 @@ namespace Orchard.FileSystems.WebSite {
}
private void BindSignal(string virtualPath) {
+ BindSignal(virtualPath, _thunk.Signal);
+
+ }
+
+ private void BindSignal(string virtualPath, CacheItemRemovedCallback callback) {
var cacheDependency = HostingEnvironment.VirtualPathProvider.GetCacheDependency(
virtualPath,
new[] { virtualPath },
@@ -92,7 +101,7 @@ namespace Orchard.FileSystems.WebSite {
Cache.NoAbsoluteExpiration,
Cache.NoSlidingExpiration,
CacheItemPriority.NotRemovable,
- _thunk.Signal);
+ callback);
}
public void Signal(string key, object value, CacheItemRemovedReason reason) {