mirror of
				https://github.com/OrchardCMS/Orchard.git
				synced 2025-10-25 10:59:18 +08:00 
			
		
		
		
	Extensions are not enabled any more if they can't actually be loaded, fixes #2437
This commit is contained in:
		| @@ -194,6 +194,10 @@ Features: | |||||||
|                 throw new NotImplementedException(); |                 throw new NotImplementedException(); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             public bool LoaderIsSuitable(ExtensionDescriptor descriptor) { | ||||||
|  |                 throw new NotImplementedException(); | ||||||
|  |             } | ||||||
|  |  | ||||||
|             #endregion |             #endregion | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -114,6 +114,10 @@ namespace Orchard.Tests.Environment.Extensions { | |||||||
|                 throw new NotImplementedException(); |                 throw new NotImplementedException(); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             public bool LoaderIsSuitable(ExtensionDescriptor descriptor) { | ||||||
|  |                 throw new NotImplementedException(); | ||||||
|  |             } | ||||||
|  |  | ||||||
|             #endregion |             #endregion | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -119,6 +119,10 @@ namespace Orchard.Tests.Environment.Extensions { | |||||||
|                 throw new NotImplementedException(); |                 throw new NotImplementedException(); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             public bool LoaderIsSuitable(ExtensionDescriptor descriptor) { | ||||||
|  |                 throw new NotImplementedException(); | ||||||
|  |             } | ||||||
|  |  | ||||||
|             #endregion |             #endregion | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -46,8 +46,7 @@ namespace Orchard.Modules.Controllers { | |||||||
|             IRecipeManager recipeManager, |             IRecipeManager recipeManager, | ||||||
|             ShellDescriptor shellDescriptor, |             ShellDescriptor shellDescriptor, | ||||||
|             ShellSettings shellSettings, |             ShellSettings shellSettings, | ||||||
|             IShapeFactory shapeFactory) |             IShapeFactory shapeFactory) { | ||||||
|         { |  | ||||||
|             Services = services; |             Services = services; | ||||||
|             _extensionDisplayEventHandler = extensionDisplayEventHandlers.FirstOrDefault(); |             _extensionDisplayEventHandler = extensionDisplayEventHandlers.FirstOrDefault(); | ||||||
|             _moduleService = moduleService; |             _moduleService = moduleService; | ||||||
| @@ -158,7 +157,7 @@ namespace Orchard.Modules.Controllers { | |||||||
|             try { |             try { | ||||||
|                 _recipeManager.Execute(recipe); |                 _recipeManager.Execute(recipe); | ||||||
|             } |             } | ||||||
|             catch(Exception e) { |             catch (Exception e) { | ||||||
|                 Logger.Error(e, "Error while executing recipe {0} in {1}", moduleId, name); |                 Logger.Error(e, "Error while executing recipe {0} in {1}", moduleId, name); | ||||||
|                 Services.Notifier.Error(T("Recipes {0} contains  unsupported module installation steps.", recipe.Name)); |                 Services.Notifier.Error(T("Recipes {0} contains  unsupported module installation steps.", recipe.Name)); | ||||||
|             } |             } | ||||||
| @@ -177,12 +176,12 @@ namespace Orchard.Modules.Controllers { | |||||||
|             IEnumerable<ModuleFeature> features = _featureManager.GetAvailableFeatures() |             IEnumerable<ModuleFeature> features = _featureManager.GetAvailableFeatures() | ||||||
|                 .Where(f => !DefaultExtensionTypes.IsTheme(f.Extension.ExtensionType)) |                 .Where(f => !DefaultExtensionTypes.IsTheme(f.Extension.ExtensionType)) | ||||||
|                 .Select(f => new ModuleFeature { |                 .Select(f => new ModuleFeature { | ||||||
|                                 Descriptor = f, |                     Descriptor = f, | ||||||
|                                 IsEnabled = _shellDescriptor.Features.Any(sf => sf.Name == f.Id), |                     IsEnabled = _shellDescriptor.Features.Any(sf => sf.Name == f.Id), | ||||||
|                                 IsRecentlyInstalled = _moduleService.IsRecentlyInstalled(f.Extension), |                     IsRecentlyInstalled = _moduleService.IsRecentlyInstalled(f.Extension), | ||||||
|                                 NeedsUpdate = featuresThatNeedUpdate.Contains(f.Id), |                     NeedsUpdate = featuresThatNeedUpdate.Contains(f.Id), | ||||||
|                                 DependentFeatures = _moduleService.GetDependentFeatures(f.Id).Where(x => x.Id != f.Id).ToList() |                     DependentFeatures = _moduleService.GetDependentFeatures(f.Id).Where(x => x.Id != f.Id).ToList() | ||||||
|                             }) |                 }) | ||||||
|                 .ToList(); |                 .ToList(); | ||||||
|  |  | ||||||
|             return View(new FeaturesViewModel { |             return View(new FeaturesViewModel { | ||||||
| @@ -212,13 +211,13 @@ namespace Orchard.Modules.Controllers { | |||||||
|                     case FeaturesBulkAction.None: |                     case FeaturesBulkAction.None: | ||||||
|                         break; |                         break; | ||||||
|                     case FeaturesBulkAction.Enable: |                     case FeaturesBulkAction.Enable: | ||||||
|                         _moduleService.EnableFeatures(disabledFeatures, force == true); |                         EnableFeatures(disabledFeatures, force == true); | ||||||
|                         break; |                         break; | ||||||
|                     case FeaturesBulkAction.Disable: |                     case FeaturesBulkAction.Disable: | ||||||
|                         _moduleService.DisableFeatures(enabledFeatures, force == true); |                         _moduleService.DisableFeatures(enabledFeatures, force == true); | ||||||
|                         break; |                         break; | ||||||
|                     case FeaturesBulkAction.Toggle: |                     case FeaturesBulkAction.Toggle: | ||||||
|                         _moduleService.EnableFeatures(disabledFeatures, force == true); |                         EnableFeatures(disabledFeatures, force == true); | ||||||
|                         _moduleService.DisableFeatures(enabledFeatures, force == true); |                         _moduleService.DisableFeatures(enabledFeatures, force == true); | ||||||
|                         break; |                         break; | ||||||
|                     case FeaturesBulkAction.Update: |                     case FeaturesBulkAction.Update: | ||||||
| @@ -250,5 +249,16 @@ namespace Orchard.Modules.Controllers { | |||||||
|         private bool ExtensionIsAllowed(ExtensionDescriptor extensionDescriptor) { |         private bool ExtensionIsAllowed(ExtensionDescriptor extensionDescriptor) { | ||||||
|             return _shellSettings.Modules.Length == 0 || _shellSettings.Modules.Contains(extensionDescriptor.Id); |             return _shellSettings.Modules.Length == 0 || _shellSettings.Modules.Contains(extensionDescriptor.Id); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         private void EnableFeatures(List<string> disabledFeatures, bool force) { | ||||||
|  |             foreach (var feature in disabledFeatures) { | ||||||
|  |                 if (_featureManager.HasLoader(feature)) { | ||||||
|  |                     _moduleService.EnableFeatures(disabledFeatures, force); | ||||||
|  |                 } | ||||||
|  |                 else { | ||||||
|  |                     Services.Notifier.Error(T("No loader found for feature's (\"{0}\") exension!", feature)); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -11,10 +11,12 @@ namespace Orchard.Environment.Extensions.Loaders { | |||||||
|     public class CoreExtensionLoader : ExtensionLoaderBase { |     public class CoreExtensionLoader : ExtensionLoaderBase { | ||||||
|         private const string CoreAssemblyName = "Orchard.Core"; |         private const string CoreAssemblyName = "Orchard.Core"; | ||||||
|         private readonly IAssemblyLoader _assemblyLoader; |         private readonly IAssemblyLoader _assemblyLoader; | ||||||
|  |         private readonly IDependenciesFolder _dependenciesFolder; | ||||||
|  |  | ||||||
|         public CoreExtensionLoader(IDependenciesFolder dependenciesFolder, IAssemblyLoader assemblyLoader) |         public CoreExtensionLoader(IAssemblyLoader assemblyLoader, IDependenciesFolder dependenciesFolder) | ||||||
|             : base(dependenciesFolder) { |             : base(dependenciesFolder) { | ||||||
|             _assemblyLoader = assemblyLoader; |             _assemblyLoader = assemblyLoader; | ||||||
|  |             _dependenciesFolder = dependenciesFolder; | ||||||
|  |  | ||||||
|             Logger = NullLogger.Instance; |             Logger = NullLogger.Instance; | ||||||
|         } |         } | ||||||
| @@ -59,6 +61,15 @@ namespace Orchard.Environment.Extensions.Loaders { | |||||||
|             }; |             }; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         public override bool LoaderIsSuitable(ExtensionDescriptor descriptor) { | ||||||
|  |             var dependency = _dependenciesFolder.GetDescriptor(descriptor.Id); | ||||||
|  |             if (dependency != null && dependency.LoaderName == this.Name) { | ||||||
|  |                 return _assemblyLoader.Load(CoreAssemblyName) != null; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         private static bool IsTypeFromModule(Type type, ExtensionDescriptor descriptor) { |         private static bool IsTypeFromModule(Type type, ExtensionDescriptor descriptor) { | ||||||
|             return (type.Namespace + ".").StartsWith(CoreAssemblyName + "." + descriptor.Id + "."); |             return (type.Namespace + ".").StartsWith(CoreAssemblyName + "." + descriptor.Id + "."); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -212,6 +212,20 @@ namespace Orchard.Environment.Extensions.Loaders { | |||||||
|             return dependencies; |             return dependencies; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         public override bool LoaderIsSuitable(ExtensionDescriptor descriptor) { | ||||||
|  |             var dependency = _dependenciesFolder.GetDescriptor(descriptor.Id); | ||||||
|  |             if (dependency != null && dependency.LoaderName == this.Name) { | ||||||
|  |                 var projectPath = GetProjectPath(descriptor); | ||||||
|  |                 if (projectPath == null) { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 return _buildManager.GetCompiledAssembly(projectPath) != null; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         private void AddDependencies(string projectPath, HashSet<string> currentSet) { |         private void AddDependencies(string projectPath, HashSet<string> currentSet) { | ||||||
|             // Skip files from locations other than "~/Modules" and "~/Themes" etc. |             // Skip files from locations other than "~/Modules" and "~/Themes" etc. | ||||||
|             if (string.IsNullOrEmpty(PrefixMatch(projectPath, _extensionsVirtualPathPrefixes))) { |             if (string.IsNullOrEmpty(PrefixMatch(projectPath, _extensionsVirtualPathPrefixes))) { | ||||||
|   | |||||||
| @@ -57,5 +57,7 @@ namespace Orchard.Environment.Extensions.Loaders { | |||||||
|         public virtual IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency) { |         public virtual IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency) { | ||||||
|             return Enumerable.Empty<string>(); |             return Enumerable.Empty<string>(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         public abstract bool LoaderIsSuitable(ExtensionDescriptor descriptor); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -59,5 +59,7 @@ namespace Orchard.Environment.Extensions.Loaders { | |||||||
|         /// For example, Razor or WebForms views needs to be recompiled when a dependency of a module changes. |         /// For example, Razor or WebForms views needs to be recompiled when a dependency of a module changes. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|         IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency); |         IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency); | ||||||
|  |  | ||||||
|  |         bool LoaderIsSuitable(ExtensionDescriptor descriptor); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -19,6 +19,7 @@ namespace Orchard.Environment.Extensions.Loaders { | |||||||
|         private readonly IAssemblyProbingFolder _assemblyProbingFolder; |         private readonly IAssemblyProbingFolder _assemblyProbingFolder; | ||||||
|         private readonly IVirtualPathProvider _virtualPathProvider; |         private readonly IVirtualPathProvider _virtualPathProvider; | ||||||
|         private readonly IVirtualPathMonitor _virtualPathMonitor; |         private readonly IVirtualPathMonitor _virtualPathMonitor; | ||||||
|  |         private readonly IDependenciesFolder _dependenciesFolder; | ||||||
|  |  | ||||||
|         public PrecompiledExtensionLoader( |         public PrecompiledExtensionLoader( | ||||||
|             IHostEnvironment hostEnvironment, |             IHostEnvironment hostEnvironment, | ||||||
| @@ -31,6 +32,7 @@ namespace Orchard.Environment.Extensions.Loaders { | |||||||
|             _assemblyProbingFolder = assemblyProbingFolder; |             _assemblyProbingFolder = assemblyProbingFolder; | ||||||
|             _virtualPathProvider = virtualPathProvider; |             _virtualPathProvider = virtualPathProvider; | ||||||
|             _virtualPathMonitor = virtualPathMonitor; |             _virtualPathMonitor = virtualPathMonitor; | ||||||
|  |             _dependenciesFolder = dependenciesFolder; | ||||||
|  |  | ||||||
|             Logger = NullLogger.Instance; |             Logger = NullLogger.Instance; | ||||||
|         } |         } | ||||||
| @@ -166,7 +168,7 @@ namespace Orchard.Environment.Extensions.Loaders { | |||||||
|                     Loader = this, |                     Loader = this, | ||||||
|                     Name = Path.GetFileNameWithoutExtension(path), |                     Name = Path.GetFileNameWithoutExtension(path), | ||||||
|                     VirtualPath = path |                     VirtualPath = path | ||||||
|                 } ) |                 }) | ||||||
|                 .ToList(); |                 .ToList(); | ||||||
|  |  | ||||||
|             Logger.Information("Done probing references for module '{0}'", descriptor.Id); |             Logger.Information("Done probing references for module '{0}'", descriptor.Id); | ||||||
| @@ -244,5 +246,14 @@ namespace Orchard.Environment.Extensions.Loaders { | |||||||
|  |  | ||||||
|             return assemblyPath; |             return assemblyPath; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         public override bool LoaderIsSuitable(ExtensionDescriptor descriptor) { | ||||||
|  |             var dependency = _dependenciesFolder.GetDescriptor(descriptor.Id); | ||||||
|  |             if (dependency != null && dependency.LoaderName == this.Name) { | ||||||
|  |                 return _assemblyProbingFolder.AssemblyExists(descriptor.Id); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -8,10 +8,12 @@ using Orchard.Logging; | |||||||
| namespace Orchard.Environment.Extensions.Loaders { | namespace Orchard.Environment.Extensions.Loaders { | ||||||
|     public class RawThemeExtensionLoader : ExtensionLoaderBase { |     public class RawThemeExtensionLoader : ExtensionLoaderBase { | ||||||
|         private readonly IVirtualPathProvider _virtualPathProvider; |         private readonly IVirtualPathProvider _virtualPathProvider; | ||||||
|  |         private readonly IDependenciesFolder _dependenciesFolder; | ||||||
|  |  | ||||||
|         public RawThemeExtensionLoader(IDependenciesFolder dependenciesFolder, IVirtualPathProvider virtualPathProvider) |         public RawThemeExtensionLoader(IDependenciesFolder dependenciesFolder, IVirtualPathProvider virtualPathProvider) | ||||||
|             : base(dependenciesFolder) { |             : base(dependenciesFolder) { | ||||||
|             _virtualPathProvider = virtualPathProvider; |             _virtualPathProvider = virtualPathProvider; | ||||||
|  |             _dependenciesFolder = dependenciesFolder; | ||||||
|  |  | ||||||
|             Logger = NullLogger.Instance; |             Logger = NullLogger.Instance; | ||||||
|         } |         } | ||||||
| @@ -26,12 +28,12 @@ namespace Orchard.Environment.Extensions.Loaders { | |||||||
|                 return null; |                 return null; | ||||||
|  |  | ||||||
|             // Temporary - theme without own project should be under ~/themes |             // Temporary - theme without own project should be under ~/themes | ||||||
|             if (descriptor.Location.StartsWith("~/Themes",StringComparison.InvariantCultureIgnoreCase)) { |             if (descriptor.Location.StartsWith("~/Themes", StringComparison.InvariantCultureIgnoreCase)) { | ||||||
|                 string projectPath = _virtualPathProvider.Combine(descriptor.Location, descriptor.Id, |                 string projectPath = _virtualPathProvider.Combine(descriptor.Location, descriptor.Id, | ||||||
|                                            descriptor.Id + ".csproj"); |                                            descriptor.Id + ".csproj"); | ||||||
|  |  | ||||||
|                 // ignore themes including a .csproj in this loader |                 // ignore themes including a .csproj in this loader | ||||||
|                 if ( _virtualPathProvider.FileExists(projectPath) ) { |                 if (_virtualPathProvider.FileExists(projectPath)) { | ||||||
|                     return null; |                     return null; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| @@ -39,7 +41,7 @@ namespace Orchard.Environment.Extensions.Loaders { | |||||||
|                                                 descriptor.Id + ".dll"); |                                                 descriptor.Id + ".dll"); | ||||||
|  |  | ||||||
|                 // ignore themes with /bin in this loader |                 // ignore themes with /bin in this loader | ||||||
|                 if ( _virtualPathProvider.FileExists(assemblyPath) ) |                 if (_virtualPathProvider.FileExists(assemblyPath)) | ||||||
|                     return null; |                     return null; | ||||||
|  |  | ||||||
|                 return new ExtensionProbeEntry { |                 return new ExtensionProbeEntry { | ||||||
| @@ -64,5 +66,14 @@ namespace Orchard.Environment.Extensions.Loaders { | |||||||
|                 ExportedTypes = new Type[0] |                 ExportedTypes = new Type[0] | ||||||
|             }; |             }; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         public override bool LoaderIsSuitable(ExtensionDescriptor descriptor) { | ||||||
|  |             var dependency = _dependenciesFolder.GetDescriptor(descriptor.Id); | ||||||
|  |             if (dependency != null && dependency.LoaderName == this.Name) { | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -13,12 +13,14 @@ namespace Orchard.Environment.Extensions.Loaders { | |||||||
|     public class ReferencedExtensionLoader : ExtensionLoaderBase { |     public class ReferencedExtensionLoader : ExtensionLoaderBase { | ||||||
|         private readonly IVirtualPathProvider _virtualPathProvider; |         private readonly IVirtualPathProvider _virtualPathProvider; | ||||||
|         private readonly IBuildManager _buildManager; |         private readonly IBuildManager _buildManager; | ||||||
|  |         private readonly IDependenciesFolder _dependenciesFolder; | ||||||
|  |  | ||||||
|         public ReferencedExtensionLoader(IDependenciesFolder dependenciesFolder, IVirtualPathProvider virtualPathProvider, IBuildManager buildManager) |         public ReferencedExtensionLoader(IDependenciesFolder dependenciesFolder, IVirtualPathProvider virtualPathProvider, IBuildManager buildManager) | ||||||
|             : base(dependenciesFolder) { |             : base(dependenciesFolder) { | ||||||
|  |  | ||||||
|             _virtualPathProvider = virtualPathProvider; |             _virtualPathProvider = virtualPathProvider; | ||||||
|             _buildManager = buildManager; |             _buildManager = buildManager; | ||||||
|  |             _dependenciesFolder = dependenciesFolder; | ||||||
|             Logger = NullLogger.Instance; |             Logger = NullLogger.Instance; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -82,5 +84,14 @@ namespace Orchard.Environment.Extensions.Loaders { | |||||||
|                 ExportedTypes = assembly.GetExportedTypes() |                 ExportedTypes = assembly.GetExportedTypes() | ||||||
|             }; |             }; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         public override bool LoaderIsSuitable(ExtensionDescriptor descriptor) { | ||||||
|  |             var dependency = _dependenciesFolder.GetDescriptor(descriptor.Id); | ||||||
|  |             if (dependency != null && dependency.LoaderName == this.Name) { | ||||||
|  |                 return _buildManager.GetReferencedAssembly(descriptor.Id) != null; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ using System.Linq; | |||||||
| using Orchard.Environment.Descriptor; | using Orchard.Environment.Descriptor; | ||||||
| using Orchard.Environment.Descriptor.Models; | using Orchard.Environment.Descriptor.Models; | ||||||
| using Orchard.Environment.Extensions; | using Orchard.Environment.Extensions; | ||||||
| using Orchard.Environment.Extensions.Helpers; | using Orchard.Environment.Extensions.Loaders; | ||||||
| using Orchard.Environment.Extensions.Models; | using Orchard.Environment.Extensions.Models; | ||||||
| using Orchard.Localization; | using Orchard.Localization; | ||||||
| using Orchard.Logging; | using Orchard.Logging; | ||||||
| @@ -13,6 +13,7 @@ namespace Orchard.Environment.Features { | |||||||
|     public class FeatureManager : IFeatureManager { |     public class FeatureManager : IFeatureManager { | ||||||
|         private readonly IExtensionManager _extensionManager; |         private readonly IExtensionManager _extensionManager; | ||||||
|         private readonly IShellDescriptorManager _shellDescriptorManager; |         private readonly IShellDescriptorManager _shellDescriptorManager; | ||||||
|  |         private readonly IEnumerable<IExtensionLoader> _loaders; | ||||||
|  |  | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Delegate to notify about feature dependencies. |         /// Delegate to notify about feature dependencies. | ||||||
| @@ -21,10 +22,11 @@ namespace Orchard.Environment.Features { | |||||||
|  |  | ||||||
|         public FeatureManager( |         public FeatureManager( | ||||||
|             IExtensionManager extensionManager, |             IExtensionManager extensionManager, | ||||||
|             IShellDescriptorManager shellDescriptorManager) { |             IShellDescriptorManager shellDescriptorManager, | ||||||
|  |             IEnumerable<IExtensionLoader> loaders) { | ||||||
|             _extensionManager = extensionManager; |             _extensionManager = extensionManager; | ||||||
|             _shellDescriptorManager = shellDescriptorManager; |             _shellDescriptorManager = shellDescriptorManager; | ||||||
|  |             _loaders = loaders; | ||||||
|             T = NullLocalizer.Instance; |             T = NullLocalizer.Instance; | ||||||
|             Logger = NullLogger.Instance; |             Logger = NullLogger.Instance; | ||||||
|         } |         } | ||||||
| @@ -161,6 +163,22 @@ namespace Orchard.Environment.Features { | |||||||
|             return GetAffectedFeatures(featureId, availableFeatures, getEnabledDependants); |             return GetAffectedFeatures(featureId, availableFeatures, getEnabledDependants); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         public bool HasLoader(string featureId) { | ||||||
|  |             var descriptor = _extensionManager | ||||||
|  |                 .AvailableExtensions() | ||||||
|  |                 .Where(d => DefaultExtensionTypes.IsModule(d.ExtensionType) || DefaultExtensionTypes.IsTheme(d.ExtensionType)) | ||||||
|  |                 .OrderBy(d => d.Id) | ||||||
|  |                 .FirstOrDefault(e => e.Id == featureId || e.Features.Select(f => f.Id).Contains(featureId)); | ||||||
|  |  | ||||||
|  |             foreach (var loader in _loaders) { | ||||||
|  |                 if (loader.LoaderIsSuitable(descriptor)) { | ||||||
|  |                     return true; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Enables a feature. |         /// Enables a feature. | ||||||
|         /// </summary> |         /// </summary> | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| using Orchard.Environment.Extensions.Models; | using Orchard.Environment.Extensions.Models; | ||||||
|  | using Orchard.Environment.Extensions; | ||||||
|  |  | ||||||
| namespace Orchard.Environment.Features { | namespace Orchard.Environment.Features { | ||||||
|     public delegate void FeatureDependencyNotificationHandler(string messageFormat, string featureId, IEnumerable<string> featureIds); |     public delegate void FeatureDependencyNotificationHandler(string messageFormat, string featureId, IEnumerable<string> featureIds); | ||||||
| @@ -61,5 +62,12 @@ namespace Orchard.Environment.Features { | |||||||
|         /// <param name="featureId">ID of the feature to check.</param> |         /// <param name="featureId">ID of the feature to check.</param> | ||||||
|         /// <returns>An enumeration with dependent feature IDs.</returns> |         /// <returns>An enumeration with dependent feature IDs.</returns> | ||||||
|         IEnumerable<string> GetDependentFeatures(string featureId); |         IEnumerable<string> GetDependentFeatures(string featureId); | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Checks whether the feature's extension has a loadee, i.e. a suitable <see cref="IExtensionLoader"/> can be found. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="featureId">ID of the feature to check.</param> | ||||||
|  |         /// <returns><c>True</c> if a suitable <see cref="IExtensionLoader"/> can be found.</returns> | ||||||
|  |         bool HasLoader(string featureId); | ||||||
|     } |     } | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user
	 Lombiq
					Lombiq