Refactoring a couple of method related to dynamic compilation

Abstract away WebForms syntax knowledge from extension loader
implementations.

Rename the corresponding methods to be more semantically correct.

--HG--
branch : 1.x
This commit is contained in:
Renaud Paquay
2011-05-25 20:56:02 -07:00
parent 6d0b7e1d61
commit 314c9cb9a6
9 changed files with 70 additions and 50 deletions

View File

@@ -183,15 +183,11 @@ Features:
public void Monitor(ExtensionDescriptor extension, Action<IVolatileToken> monitor) {
}
public string GetWebFormAssemblyDirective(DependencyDescriptor dependency) {
public IEnumerable<ExtensionCompilationReference> GetCompilationReferences(DependencyDescriptor dependency) {
throw new NotImplementedException();
}
public IEnumerable<string> GetWebFormVirtualDependencies(DependencyDescriptor dependency) {
throw new NotImplementedException();
}
public IEnumerable<string> GetDynamicModuleDependencies(DependencyDescriptor dependency, string virtualPath) {
public IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency) {
throw new NotImplementedException();
}

View File

@@ -104,15 +104,11 @@ namespace Orchard.Tests.Environment.Extensions {
public void Monitor(ExtensionDescriptor extension, Action<IVolatileToken> monitor) {
}
public string GetWebFormAssemblyDirective(DependencyDescriptor dependency) {
public IEnumerable<ExtensionCompilationReference> GetCompilationReferences(DependencyDescriptor dependency) {
throw new NotImplementedException();
}
public IEnumerable<string> GetWebFormVirtualDependencies(DependencyDescriptor dependency) {
throw new NotImplementedException();
}
public IEnumerable<string> GetDynamicModuleDependencies(DependencyDescriptor dependency, string virtualPath) {
public IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency) {
throw new NotImplementedException();
}

View File

@@ -109,15 +109,11 @@ namespace Orchard.Tests.Environment.Extensions {
public void Monitor(ExtensionDescriptor extension, Action<IVolatileToken> monitor) {
}
public string GetWebFormAssemblyDirective(DependencyDescriptor dependency) {
public IEnumerable<ExtensionCompilationReference> GetCompilationReferences(DependencyDescriptor dependency) {
throw new NotImplementedException();
}
public IEnumerable<string> GetWebFormVirtualDependencies(DependencyDescriptor dependency) {
throw new NotImplementedException();
}
public IEnumerable<string> GetDynamicModuleDependencies(DependencyDescriptor dependency, string virtualPath) {
public IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency) {
throw new NotImplementedException();
}

View File

@@ -48,11 +48,11 @@ namespace Orchard.Environment.Extensions.Loaders {
public override int Order { get { return 100; } }
public override string GetWebFormAssemblyDirective(DependencyDescriptor dependency) {
return string.Format("<%@ Assembly Src=\"{0}\"%>", dependency.VirtualPath);
public override IEnumerable<ExtensionCompilationReference> GetCompilationReferences(DependencyDescriptor dependency) {
yield return new ExtensionCompilationReference { BuildProviderTarget = dependency.VirtualPath };
}
public override IEnumerable<string> GetWebFormVirtualDependencies(DependencyDescriptor dependency) {
public override IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency) {
// Return csproj and all .cs files
return GetDependencies(dependency.VirtualPath);
}

View File

@@ -50,11 +50,11 @@ namespace Orchard.Environment.Extensions.Loaders {
protected abstract ExtensionEntry LoadWorker(ExtensionDescriptor descriptor);
public virtual string GetWebFormAssemblyDirective(DependencyDescriptor dependency) {
return null;
public virtual IEnumerable<ExtensionCompilationReference> GetCompilationReferences(DependencyDescriptor dependency) {
return Enumerable.Empty<ExtensionCompilationReference>();
}
public virtual IEnumerable<string> GetWebFormVirtualDependencies(DependencyDescriptor dependency) {
public virtual IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency) {
return Enumerable.Empty<string>();
}
}

View File

@@ -20,6 +20,11 @@ namespace Orchard.Environment.Extensions.Loaders {
public string VirtualPath { get; set; }
}
public class ExtensionCompilationReference {
public string AssemblyName { get; set; }
public string BuildProviderTarget { get; set; }
}
public interface IExtensionLoader {
int Order { get; }
string Name { get; }
@@ -39,7 +44,19 @@ namespace Orchard.Environment.Extensions.Loaders {
void Monitor(ExtensionDescriptor extension, Action<IVolatileToken> monitor);
string GetWebFormAssemblyDirective(DependencyDescriptor dependency);
IEnumerable<string> GetWebFormVirtualDependencies(DependencyDescriptor dependency);
/// <summary>
/// Return a list of references required to compile a component (e.g. a Razor or WebForm view)
/// depending on the given module.
/// Each reference can either be an assembly name or a file to pass to the
/// IBuildManager.GetCompiledAssembly() method (e.g. a module .csproj project file).
/// </summary>
IEnumerable<ExtensionCompilationReference> GetCompilationReferences(DependencyDescriptor dependency);
/// <summary>
/// Return the list of dependencies (as virtual path) of the given module.
/// If any of the dependency returned in the list is updated, a component depending
/// on the assembly produced for the module must be re-compiled.
/// For example, Razor or WebForms views needs to be recompiled when a dependency of a module changes.
/// </summary>
IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency);
}
}

View File

@@ -40,11 +40,11 @@ namespace Orchard.Environment.Extensions.Loaders {
public override int Order { get { return 30; } }
public override string GetWebFormAssemblyDirective(DependencyDescriptor dependency) {
return string.Format("<%@ Assembly Name=\"{0}\"%>", dependency.Name);
public override IEnumerable<ExtensionCompilationReference> GetCompilationReferences(DependencyDescriptor dependency) {
yield return new ExtensionCompilationReference { AssemblyName = dependency.Name };
}
public override IEnumerable<string> GetWebFormVirtualDependencies(DependencyDescriptor dependency) {
public override IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency) {
yield return _assemblyProbingFolder.GetAssemblyVirtualPath(dependency.Name);
}

View File

@@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Hosting;
using Orchard.Environment.Extensions.Loaders;
@@ -59,11 +60,11 @@ namespace Orchard.FileSystems.Dependencies {
var dependencies =
virtualPathDependencies
.OfType<string>()
.Concat(file.Loaders.SelectMany(dl => dl.Loader.GetWebFormVirtualDependencies(dl.Descriptor)));
.Concat(file.Loaders.SelectMany(dl => dl.Loader.GetVirtualPathDependencies(dl.Descriptor)));
if (Logger.IsEnabled(LogLevel.Debug)) {
Logger.Debug("GetFileHash(\"{0}\") - virtual path dependencies:", virtualPath);
foreach(var dependency in dependencies) {
foreach (var dependency in dependencies) {
Logger.Debug(" Dependency: \"{0}\"", dependency);
}
}
@@ -129,13 +130,13 @@ namespace Orchard.FileSystems.Dependencies {
if (loader == null)
return null;
var directive = loader.GetWebFormAssemblyDirective(dependencyDescriptor);
if (string.IsNullOrEmpty(directive))
var references = loader.GetCompilationReferences(dependencyDescriptor).ToList();
if (!references.Any())
return null;
return new VirtualFileOverride {
ModuleName = moduleName,
Directive = directive,
Directive = CreateAssemblyDirectivesString(references),
Loaders = new[] { new DependencyLoader { Loader = loader, Descriptor = dependencyDescriptor } }
};
}
@@ -150,25 +151,40 @@ namespace Orchard.FileSystems.Dependencies {
if (extension == null)
return null;
var loaders = _loaders
var dependencyLoaders = _loaders
.SelectMany(loader => _dependenciesFolder
.LoadDescriptors()
.Where(d => d.LoaderName == loader.Name),
(loader, desr) => new DependencyLoader { Loader = loader, Descriptor = desr });
(loader, desr) => new DependencyLoader { Loader = loader, Descriptor = desr })
.ToList();
var directive = loaders
.Aggregate("", (s, dl) => s + dl.Loader.GetWebFormAssemblyDirective(dl.Descriptor));
var references = dependencyLoaders
.SelectMany(dl => dl.Loader.GetCompilationReferences(dl.Descriptor))
.ToList();
if (string.IsNullOrEmpty(directive))
if (!references.Any())
return null;
return new VirtualFileOverride {
ModuleName = "",
Directive = directive,
Loaders = loaders
Directive = CreateAssemblyDirectivesString(references),
Loaders = dependencyLoaders
};
}
private string CreateAssemblyDirectivesString(IEnumerable<ExtensionCompilationReference> references) {
var sb = new StringBuilder();
foreach (var reference in references) {
if (!string.IsNullOrEmpty(reference.AssemblyName)) {
sb.AppendFormat("<%@ Assembly Name=\"{0}\"%>", reference.AssemblyName);
}
if (!string.IsNullOrEmpty(reference.BuildProviderTarget)) {
sb.AppendFormat("<%@ Assembly Src=\"{0}\"%>", reference.BuildProviderTarget);
}
}
return sb.ToString();
}
private static string ModuleMatch(string virtualPath, string prefix) {
var index = virtualPath.IndexOf('/', prefix.Length, virtualPath.Length - prefix.Length);
if (index < 0)

View File

@@ -66,25 +66,24 @@ namespace Orchard.Mvc.ViewEngines.Razor {
.Select(loader => new {
loader,
descriptor,
directive = loader.GetWebFormAssemblyDirective(descriptor),
dependencies = loader.GetWebFormVirtualDependencies(descriptor)
references = loader.GetCompilationReferences(descriptor),
dependencies = loader.GetVirtualPathDependencies(descriptor)
}));
foreach (var entry in entries) {
if (entry.directive != null) {
if (entry.directive.StartsWith("<%@ Assembly Name=\"")) {
var assembly = _assemblyLoader.Load(entry.descriptor.Name);
foreach (var reference in entry.references) {
if (!string.IsNullOrEmpty(reference.AssemblyName)) {
var assembly = _assemblyLoader.Load(reference.AssemblyName);
if (assembly != null)
provider.AssemblyBuilder.AddAssemblyReference(assembly);
}
else if (entry.directive.StartsWith("<%@ Assembly Src=\"")) {
if (!string.IsNullOrEmpty(reference.BuildProviderTarget)) {
// Returned assembly may be null if the .csproj file doesn't containt any .cs file, for example
var assembly = _buildManager.GetCompiledAssembly(entry.descriptor.VirtualPath);
var assembly = _buildManager.GetCompiledAssembly(reference.BuildProviderTarget);
if (assembly != null)
provider.AssemblyBuilder.AddAssemblyReference(assembly);
}
}
}
//PERF: Ensure each virtual path is present only once in the list of dependencies
@@ -99,7 +98,7 @@ namespace Orchard.Mvc.ViewEngines.Razor {
private DependencyDescriptor GetModuleDependencyDescriptor(string virtualPath) {
var appRelativePath = VirtualPathUtility.ToAppRelative(virtualPath);
var prefix = PrefixMatch(appRelativePath, new [] { "~/Modules/", "~/Core/"});
var prefix = PrefixMatch(appRelativePath, new[] { "~/Modules/", "~/Core/" });
if (prefix == null)
return null;