mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-12-03 12:03:51 +08:00
Dynamic compilation bug fix
Symptom: One the first modification to a source file starts a dynamic compilation. After that, changes are ignored. Fix: The problem was that we need to override the "FileHash" value returned for csproj files to include the hash of all source files. This is so that any changes to any source file will notify ASP.NET that the .csproj file needs to be recompiled using a the corresponding build provider. --HG-- branch : dev
This commit is contained in:
@@ -108,6 +108,10 @@ namespace Orchard.Tests.Environment.Extensions {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetFileDependencies(DependencyDescriptor dependency, string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
@@ -108,6 +108,10 @@ namespace Orchard.Tests.Environment.Extensions {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetFileDependencies(DependencyDescriptor dependency, string virtualPath) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,16 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
return GetDependencies(dependency.VirtualPath);
|
||||
}
|
||||
|
||||
public override IEnumerable<string> GetFileDependencies(DependencyDescriptor dependency, string virtualPath){
|
||||
var path1 = virtualPath.StartsWith("~") ? virtualPath : "~" + virtualPath;
|
||||
var path2 = dependency.VirtualPath.StartsWith("~") ? dependency.VirtualPath : "~" + dependency.VirtualPath;
|
||||
|
||||
if (StringComparer.OrdinalIgnoreCase.Equals(path1, path2)) {
|
||||
return GetSourceFiles(virtualPath);
|
||||
}
|
||||
return base.GetFileDependencies(dependency, virtualPath);
|
||||
}
|
||||
|
||||
public override void Monitor(ExtensionDescriptor descriptor, Action<IVolatileToken> monitor) {
|
||||
// Monitor .csproj and all .cs files
|
||||
string projectPath = GetProjectPath(descriptor);
|
||||
|
||||
@@ -57,5 +57,9 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
public virtual IEnumerable<string> GetWebFormVirtualDependencies(DependencyDescriptor dependency) {
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
|
||||
public virtual IEnumerable<string> GetFileDependencies(DependencyDescriptor dependency, string virtualPath) {
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,5 +42,6 @@ namespace Orchard.Environment.Extensions.Loaders {
|
||||
|
||||
string GetWebFormAssemblyDirective(DependencyDescriptor dependency);
|
||||
IEnumerable<string> GetWebFormVirtualDependencies(DependencyDescriptor dependency);
|
||||
IEnumerable<string> GetFileDependencies(DependencyDescriptor dependency, string virtualPath);
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,7 @@ namespace Orchard.Environment {
|
||||
builder.RegisterType<DefaultHostEnvironment>().As<IHostEnvironment>().SingleInstance();
|
||||
builder.RegisterType<DefaultBuildManager>().As<IBuildManager>().SingleInstance();
|
||||
builder.RegisterType<WebFormVirtualPathProvider>().As<ICustomVirtualPathProvider>().SingleInstance();
|
||||
builder.RegisterType<DynamicModuleVirtualPathProvider>().As<ICustomVirtualPathProvider>().SingleInstance();
|
||||
builder.RegisterType<AppDataFolderRoot>().As<IAppDataFolderRoot>().SingleInstance();
|
||||
builder.RegisterType<DefaultExtensionCompiler>().As<IExtensionCompiler>().SingleInstance();
|
||||
builder.RegisterType<DefaultProjectFileParser>().As<IProjectFileParser>().SingleInstance();
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Hosting;
|
||||
using Orchard.Environment.Extensions.Loaders;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.Logging;
|
||||
|
||||
namespace Orchard.FileSystems.Dependencies {
|
||||
public class DynamicModuleVirtualPathProvider : VirtualPathProvider, ICustomVirtualPathProvider {
|
||||
private readonly IDependenciesFolder _dependenciesFolder;
|
||||
private readonly IEnumerable<IExtensionLoader> _loaders;
|
||||
private readonly string[] _modulesPrefixes = { "~/Modules/", "/Modules/" };
|
||||
|
||||
public DynamicModuleVirtualPathProvider(IDependenciesFolder dependenciesFolder, IEnumerable<IExtensionLoader> loaders) {
|
||||
_dependenciesFolder = dependenciesFolder;
|
||||
_loaders = loaders;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public override bool DirectoryExists(string virtualDir) {
|
||||
return Previous.DirectoryExists(virtualDir);
|
||||
}
|
||||
|
||||
public override bool FileExists(string virtualPath) {
|
||||
return Previous.FileExists(virtualPath);
|
||||
}
|
||||
|
||||
public override string GetFileHash(string virtualPath, IEnumerable virtualPathDependencies) {
|
||||
var result = GetFileHashWorker(virtualPath, virtualPathDependencies);
|
||||
//Logger.Information("GetFileHash(\"{0}\"): {1}", virtualPath, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private string GetFileHashWorker(string virtualPath, IEnumerable virtualPathDependencies) {
|
||||
var desc = GetDependencyDescriptor(virtualPath);
|
||||
if (desc != null) {
|
||||
|
||||
var loader = _loaders.Where(l => l.Name == desc.LoaderName).FirstOrDefault();
|
||||
if (loader != null) {
|
||||
|
||||
var otherDependencies = loader.GetFileDependencies(desc, virtualPath);
|
||||
if (otherDependencies.Any()) {
|
||||
|
||||
var allDependencies = virtualPathDependencies.OfType<string>().Concat(otherDependencies);
|
||||
|
||||
if (Logger.IsEnabled(LogLevel.Debug)) {
|
||||
Logger.Debug("GetFileHash(\"{0}\") - virtual path dependencies:", virtualPath);
|
||||
foreach (var dependency in allDependencies) {
|
||||
Logger.Debug(" Dependency: \"{0}\"", dependency);
|
||||
}
|
||||
}
|
||||
|
||||
return base.GetFileHash(virtualPath, allDependencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
return base.GetFileHash(virtualPath, virtualPathDependencies);
|
||||
}
|
||||
|
||||
public override VirtualFile GetFile(string virtualPath) {
|
||||
return Previous.GetFile(virtualPath);
|
||||
}
|
||||
|
||||
private DependencyDescriptor GetDependencyDescriptor(string virtualPath) {
|
||||
var prefix = PrefixMatch(virtualPath, _modulesPrefixes);
|
||||
if (prefix == null)
|
||||
return null;
|
||||
|
||||
var moduleName = ModuleMatch(virtualPath, prefix);
|
||||
if (moduleName == null)
|
||||
return null;
|
||||
|
||||
return _dependenciesFolder.GetDescriptor(moduleName);
|
||||
}
|
||||
|
||||
private string ModuleMatch(string virtualPath, string prefix) {
|
||||
var index = virtualPath.IndexOf('/', prefix.Length, virtualPath.Length - prefix.Length);
|
||||
if (index < 0)
|
||||
return null;
|
||||
|
||||
var moduleName = virtualPath.Substring(prefix.Length, index - prefix.Length);
|
||||
return (string.IsNullOrEmpty(moduleName) ? null : moduleName);
|
||||
}
|
||||
|
||||
private string PrefixMatch(string virtualPath, params string[] prefixes) {
|
||||
return prefixes
|
||||
.FirstOrDefault(p => virtualPath.StartsWith(p, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
VirtualPathProvider ICustomVirtualPathProvider.Instance {
|
||||
get { return this; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -360,6 +360,7 @@
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ContentManagement\DataMigrations\FrameworkDataMigration.cs" />
|
||||
<Compile Include="FileSystems\Dependencies\DynamicModuleVirtualPathProvider.cs" />
|
||||
<Compile Include="Utility\Hash.cs" />
|
||||
<Compile Include="Data\ISessionConfigurationCache.cs" />
|
||||
<Compile Include="Data\Migration\Generator\ISchemaCommandGenerator.cs" />
|
||||
|
||||
Reference in New Issue
Block a user