Using ExtensionMonitoringCoordinator configuration to disable monitoring

The DynamicExtensionLoader won't monitor any file if ExtensionMonitoringCoordinator
doesn't explicitly, while still loading dynamic modules. It is still better
for performance to precompile modules.

--HG--
branch : 1.x
This commit is contained in:
Sebastien Ros 2012-10-26 16:41:00 -07:00
parent 1c707dc719
commit 9e218f06f7
7 changed files with 2 additions and 206 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<HostComponents>
<Components>
<Component Type="Orchard.Environment.Extensions.Loaders.DynamicExtensionLoader">
<Component Type="Orchard.Environment.Extensions.ExtensionMonitoringCoordinator">
<Properties>
<Property Name="Disabled" Value="true"/>
</Properties>

View File

@ -59,10 +59,6 @@ namespace Orchard.Environment.Extensions.Loaders {
return GetDependencies(dependency.VirtualPath);
}
public IEnumerable<string> GetFileHashDependencies(DependencyDescriptor dependency) {
return GetDependencies(dependency.VirtualPath);
}
public override void Monitor(ExtensionDescriptor descriptor, Action<IVolatileToken> monitor) {
if (Disabled)
return;

View File

@ -173,7 +173,7 @@ namespace Orchard.Environment.Extensions.Loaders {
// A pre-compiled module is _not_ compatible with a dynamically loaded module
// because a pre-compiled module usually references a pre-compiled assembly binary
// which will have a different identity (i.e. name) from the dynamic module.
bool result = references.All(r => r.Loader.GetType() != typeof(DynamicExtensionLoader) && r.Loader.GetType() != typeof(ProbingExtensionLoader));
bool result = references.All(r => r.Loader.GetType() != typeof(DynamicExtensionLoader));
if (!result) {
Logger.Information("Extension \"{0}\" will not be loaded as pre-compiled extension because one or more referenced extension is dynamically compiled", extension.Id);
}

View File

@ -1,197 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Orchard.Environment.Extensions.Compilers;
using Orchard.Environment.Extensions.Models;
using Orchard.FileSystems.Dependencies;
using Orchard.FileSystems.VirtualPath;
using Orchard.Logging;
using Orchard.Utility.Extensions;
namespace Orchard.Environment.Extensions.Loaders {
/// <summary>
/// In case <see cref="DynamicExtensionLoader"/> is disabled, this loader will dynamically compile the assembly.
/// It won't monitor the filesystem.
/// </summary>
public class ProbingExtensionLoader : ExtensionLoaderBase {
public static readonly string[] ExtensionsVirtualPathPrefixes = { "~/Modules/", "~/Themes/" };
private readonly IBuildManager _buildManager;
private readonly IVirtualPathProvider _virtualPathProvider;
private readonly IHostEnvironment _hostEnvironment;
private readonly IAssemblyProbingFolder _assemblyProbingFolder;
private readonly IProjectFileParser _projectFileParser;
public ProbingExtensionLoader(
IBuildManager buildManager,
IVirtualPathProvider virtualPathProvider,
IHostEnvironment hostEnvironment,
IAssemblyProbingFolder assemblyProbingFolder,
IDependenciesFolder dependenciesFolder,
IProjectFileParser projectFileParser)
: base(dependenciesFolder) {
_buildManager = buildManager;
_virtualPathProvider = virtualPathProvider;
_hostEnvironment = hostEnvironment;
_assemblyProbingFolder = assemblyProbingFolder;
_projectFileParser = projectFileParser;
Logger = NullLogger.Instance;
}
public ILogger Logger { get; set; }
public bool Disabled { get; set; }
public override int Order { get { return 110; } }
public override IEnumerable<ExtensionCompilationReference> GetCompilationReferences(DependencyDescriptor dependency) {
yield return new ExtensionCompilationReference { BuildProviderTarget = dependency.VirtualPath };
}
public override void ExtensionRemoved(ExtensionLoadingContext ctx, DependencyDescriptor dependency) {
}
public override void ExtensionDeactivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension) {
}
public override void ExtensionActivated(ExtensionLoadingContext ctx, ExtensionDescriptor extension) {
}
public override IEnumerable<ExtensionReferenceProbeEntry> ProbeReferences(ExtensionDescriptor descriptor) {
if (Disabled)
return Enumerable.Empty<ExtensionReferenceProbeEntry>();
Logger.Information("Probing references for module '{0}'", descriptor.Id);
string projectPath = GetProjectPath(descriptor);
if (projectPath == null)
return Enumerable.Empty<ExtensionReferenceProbeEntry>();
var projectFile = _projectFileParser.Parse(projectPath);
var result = projectFile.References.Select(r => new ExtensionReferenceProbeEntry {
Descriptor = descriptor,
Loader = this,
Name = r.SimpleName,
VirtualPath = _virtualPathProvider.GetProjectReferenceVirtualPath(projectPath, r.SimpleName, r.Path)
});
Logger.Information("Done probing references for module '{0}'", descriptor.Id);
return result;
}
public override void ReferenceActivated(ExtensionLoadingContext context, ExtensionReferenceProbeEntry referenceEntry) {
//Note: This is the same implementation as "PrecompiledExtensionLoader"
if (string.IsNullOrEmpty(referenceEntry.VirtualPath))
return;
string sourceFileName = _virtualPathProvider.MapPath(referenceEntry.VirtualPath);
// Copy the assembly if it doesn't exist or if it is older than the source file.
bool copyAssembly =
!_assemblyProbingFolder.AssemblyExists(referenceEntry.Name) ||
File.GetLastWriteTimeUtc(sourceFileName) > _assemblyProbingFolder.GetAssemblyDateTimeUtc(referenceEntry.Name);
if (copyAssembly) {
context.CopyActions.Add(() => _assemblyProbingFolder.StoreAssembly(referenceEntry.Name, sourceFileName));
// We need to restart the appDomain if the assembly is loaded
if (_hostEnvironment.IsAssemblyLoaded(referenceEntry.Name)) {
Logger.Information("ReferenceActivated: Reference \"{0}\" is activated with newer file and its assembly is loaded, forcing AppDomain restart", referenceEntry.Name);
context.RestartAppDomain = true;
}
}
}
public override Assembly LoadReference(DependencyReferenceDescriptor reference) {
if (Disabled)
return null;
Logger.Information("Loading reference '{0}'", reference.Name);
// DynamicExtensionLoader has 2 types of references: assemblies from module bin directory
// and .csproj.
Assembly result;
if (StringComparer.OrdinalIgnoreCase.Equals(Path.GetExtension(reference.VirtualPath), ".dll"))
result = _assemblyProbingFolder.LoadAssembly(reference.Name);
else {
result = CompileAssembly(reference.Name, reference.VirtualPath);
}
Logger.Information("Done loading reference '{0}'", reference.Name);
return result;
}
public override ExtensionProbeEntry Probe(ExtensionDescriptor descriptor) {
if (Disabled)
return null;
Logger.Information("Probing for module '{0}'", descriptor.Id);
string projectPath = GetProjectPath(descriptor);
if (projectPath == null)
return null;
var result = new ExtensionProbeEntry {
Descriptor = descriptor,
Loader = this,
Priority = 50,
VirtualPath = projectPath,
VirtualPathDependencies = new string[] { projectPath },
};
Logger.Information("Done probing for module '{0}'", descriptor.Id);
return result;
}
protected override ExtensionEntry LoadWorker(ExtensionDescriptor descriptor) {
if (Disabled)
return null;
Logger.Information("Start loading dynamic extension \"{0}\"", descriptor.Name);
var assembly = _assemblyProbingFolder.LoadAssembly(descriptor.Id);
if (assembly == null) {
string projectPath = GetProjectPath(descriptor);
if (projectPath == null)
return null;
assembly = CompileAssembly(descriptor.Id, projectPath);
}
if (assembly == null)
return null;
Logger.Information("Done loading dynamic extension \"{0}\": assembly name=\"{1}\"", descriptor.Name, assembly.FullName);
return new ExtensionEntry {
Descriptor = descriptor,
Assembly = assembly,
ExportedTypes = assembly.GetExportedTypes(),
};
}
private Assembly CompileAssembly(string moduleName, string virtualPath) {
var assembly = _buildManager.GetCompiledAssembly(virtualPath);
//if (assembly != null) {
// _assemblyProbingFolder.StoreAssembly(moduleName, assembly.Location);
//}
return assembly;
}
private string GetProjectPath(ExtensionDescriptor descriptor) {
string projectPath = _virtualPathProvider.Combine(descriptor.Location, descriptor.Id,
descriptor.Id + ".csproj");
if (!_virtualPathProvider.FileExists(projectPath)) {
return null;
}
return projectPath;
}
}
}

View File

@ -103,7 +103,6 @@ namespace Orchard.Environment {
builder.RegisterType<ReferencedExtensionLoader>().As<IExtensionLoader>().SingleInstance();
builder.RegisterType<PrecompiledExtensionLoader>().As<IExtensionLoader>().SingleInstance();
builder.RegisterType<DynamicExtensionLoader>().As<IExtensionLoader>().SingleInstance();
builder.RegisterType<ProbingExtensionLoader>().As<IExtensionLoader>().SingleInstance();
builder.RegisterType<RawThemeExtensionLoader>().As<IExtensionLoader>().SingleInstance();
}
}

View File

@ -111,7 +111,6 @@ namespace Orchard.FileSystems.Dependencies {
// implementations.
return
loaderName == "DynamicExtensionLoader" ||
loaderName == "ProbingExtensionLoader" ||
loaderName == "PrecompiledExtensionLoader";
}

View File

@ -202,7 +202,6 @@
<Compile Include="Environment\Extensions\Folders\CoreModuleFolders.cs" />
<Compile Include="Environment\Extensions\Folders\IExtensionHarvester.cs" />
<Compile Include="Environment\Extensions\IExtensionMonitoringCoordinator.cs" />
<Compile Include="Environment\Extensions\Loaders\ProbingExtensionLoader.cs" />
<Compile Include="Environment\Extensions\OrchardSuppressDependencyAttribute.cs" />
<Compile Include="Environment\Features\IFeatureManager.cs" />
<Compile Include="Environment\IAssemblyNameResolver.cs" />