diff --git a/src/Orchard.Tests.Modules/CodeGeneration/Commands/CodeGenerationCommandsTests.cs b/src/Orchard.Tests.Modules/CodeGeneration/Commands/CodeGenerationCommandsTests.cs index f41c865e9..165364532 100644 --- a/src/Orchard.Tests.Modules/CodeGeneration/Commands/CodeGenerationCommandsTests.cs +++ b/src/Orchard.Tests.Modules/CodeGeneration/Commands/CodeGenerationCommandsTests.cs @@ -50,6 +50,7 @@ namespace Orchard.Tests.Modules.CodeGeneration.Commands { builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType().As(); _container = builder.Build(); diff --git a/src/Orchard.Tests.Modules/Migrations/SchemaCommandGeneratorTests.cs b/src/Orchard.Tests.Modules/Migrations/SchemaCommandGeneratorTests.cs index 9372d4d0a..1307339b5 100644 --- a/src/Orchard.Tests.Modules/Migrations/SchemaCommandGeneratorTests.cs +++ b/src/Orchard.Tests.Modules/Migrations/SchemaCommandGeneratorTests.cs @@ -88,6 +88,7 @@ namespace Orchard.Tests.Modules.Migrations { builder.RegisterType().As(); builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)); builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType().As(); _session = _sessionFactory.OpenSession(); diff --git a/src/Orchard.Tests.Modules/Packaging/Services/FileBasedProjectSystemTests.cs b/src/Orchard.Tests.Modules/Packaging/Services/FileBasedProjectSystemTests.cs index 902d45dde..5f1c54830 100644 --- a/src/Orchard.Tests.Modules/Packaging/Services/FileBasedProjectSystemTests.cs +++ b/src/Orchard.Tests.Modules/Packaging/Services/FileBasedProjectSystemTests.cs @@ -31,6 +31,7 @@ namespace Orchard.Tests.Modules.Packaging.Services { builder.RegisterType().As(); builder.RegisterInstance(new Mock().Object); builder.RegisterType().As(); + builder.RegisterType().As(); _mockedVirtualPathProvider = new Mock(); builder.RegisterInstance(_mockedVirtualPathProvider.Object).As(); diff --git a/src/Orchard.Tests.Modules/Packaging/Services/PackageInstallerTests.cs b/src/Orchard.Tests.Modules/Packaging/Services/PackageInstallerTests.cs index 59a97b051..626477065 100644 --- a/src/Orchard.Tests.Modules/Packaging/Services/PackageInstallerTests.cs +++ b/src/Orchard.Tests.Modules/Packaging/Services/PackageInstallerTests.cs @@ -31,6 +31,7 @@ namespace Orchard.Tests.Modules.Packaging.Services { builder.RegisterType().As(); builder.RegisterInstance(new Mock().Object); builder.RegisterType().As(); + builder.RegisterType().As(); _mockedVirtualPathProvider = new Mock(); builder.RegisterInstance(_mockedVirtualPathProvider.Object).As(); diff --git a/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ModuleRecipeHandlerTest.cs b/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ModuleRecipeHandlerTest.cs index e436f311d..e1af609e9 100644 --- a/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ModuleRecipeHandlerTest.cs +++ b/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ModuleRecipeHandlerTest.cs @@ -50,6 +50,7 @@ namespace Orchard.Tests.Modules.Recipes.RecipeHandlers { builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As(); builder.RegisterType().As(); diff --git a/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ThemeRecipeHandlerTest.cs b/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ThemeRecipeHandlerTest.cs index ed898f7f2..740e1aee9 100644 --- a/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ThemeRecipeHandlerTest.cs +++ b/src/Orchard.Tests.Modules/Recipes/RecipeHandlers/ThemeRecipeHandlerTest.cs @@ -53,6 +53,7 @@ namespace Orchard.Tests.Modules.Recipes.RecipeHandlers { builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As(); builder.RegisterType().As(); diff --git a/src/Orchard.Tests.Modules/Recipes/Services/RecipeManagerTests.cs b/src/Orchard.Tests.Modules/Recipes/Services/RecipeManagerTests.cs index 0b4e5a01e..540d8f922 100644 --- a/src/Orchard.Tests.Modules/Recipes/Services/RecipeManagerTests.cs +++ b/src/Orchard.Tests.Modules/Recipes/Services/RecipeManagerTests.cs @@ -73,6 +73,7 @@ namespace Orchard.Tests.Modules.Recipes.Services { builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterInstance(_folders).As(); builder.RegisterType().As(); builder.RegisterType().As(); diff --git a/src/Orchard.Tests/DataMigration/DataMigrationTests.cs b/src/Orchard.Tests/DataMigration/DataMigrationTests.cs index 2912a3646..ae4b65864 100644 --- a/src/Orchard.Tests/DataMigration/DataMigrationTests.cs +++ b/src/Orchard.Tests/DataMigration/DataMigrationTests.cs @@ -68,6 +68,7 @@ namespace Orchard.Tests.DataMigration { builder.RegisterType().As(); builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)); builder.RegisterType().As(); + builder.RegisterType().As(); _session = _sessionFactory.OpenSession(); builder.RegisterInstance(new DefaultContentManagerTests.TestSessionLocator(_session)).As(); foreach(var type in dataMigrations) { diff --git a/src/Orchard.Tests/Environment/Extensions/ExtensionLoaderCoordinatorTests.cs b/src/Orchard.Tests/Environment/Extensions/ExtensionLoaderCoordinatorTests.cs index 457a00288..a88a7576e 100644 --- a/src/Orchard.Tests/Environment/Extensions/ExtensionLoaderCoordinatorTests.cs +++ b/src/Orchard.Tests/Environment/Extensions/ExtensionLoaderCoordinatorTests.cs @@ -27,6 +27,7 @@ namespace Orchard.Tests.Environment.Extensions { builder.RegisterInstance(_folders).As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); _container = builder.Build(); _manager = _container.Resolve(); @@ -360,7 +361,7 @@ Features: Description: Contains the Phi type. "); - IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager()); + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager(), new StubAsyncTokenProvider()); var testFeature = extensionManager.AvailableExtensions() .SelectMany(x => x.Features); @@ -386,7 +387,7 @@ Features: Description: Contains the Phi type. "); - IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager()); + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager(), new StubAsyncTokenProvider()); var testFeature = extensionManager.AvailableExtensions() .SelectMany(x => x.Features); @@ -415,7 +416,7 @@ Features: Description: Contains the Phi type. "); - IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager()); + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager(), new StubAsyncTokenProvider()); var testFeature = extensionManager.AvailableExtensions() .SelectMany(x => x.Features) .Single(x => x.Id == "TestFeature"); @@ -445,7 +446,7 @@ Features: Description: Contains the Phi type. "); - IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager()); + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager(), new StubAsyncTokenProvider()); var testFeature = extensionManager.AvailableExtensions() .SelectMany(x => x.Features) .Single(x => x.Id == "TestFeature"); @@ -473,7 +474,7 @@ Features: Description: Contains the Phi type. "); - IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager()); + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager(), new StubAsyncTokenProvider()); var testModule = extensionManager.AvailableExtensions() .SelectMany(x => x.Features) .Single(x => x.Id == "TestModule"); @@ -497,7 +498,7 @@ Version: 1.0.3 OrchardVersion: 1 "); - IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager()); + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager(), new StubAsyncTokenProvider()); var minimalisticModule = extensionManager.AvailableExtensions().Single(x => x.Id == "Minimalistic"); Assert.That(minimalisticModule.Features.Count(), Is.EqualTo(1)); @@ -516,7 +517,7 @@ Version: 1.0.3 OrchardVersion: 1 "); - IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager()); + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager(), new StubAsyncTokenProvider()); var minimalisticModule = extensionManager.AvailableExtensions().Single(x => x.Id == "Minimalistic"); Assert.That(minimalisticModule.Features.Count(), Is.EqualTo(1)); diff --git a/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs b/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs index a2d91a123..4f7b6245b 100644 --- a/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs +++ b/src/Orchard.Tests/Environment/Extensions/ExtensionManagerTests.cs @@ -28,6 +28,7 @@ namespace Orchard.Tests.Environment.Extensions { builder.RegisterInstance(_folders).As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); _container = builder.Build(); _manager = _container.Resolve(); @@ -283,7 +284,7 @@ Features: Description: Contains the Phi type. "); - IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager()); + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager(), new StubAsyncTokenProvider()); var testFeature = extensionManager.AvailableExtensions() .SelectMany(x => x.Features); @@ -309,7 +310,7 @@ Features: Description: Contains the Phi type. "); - IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager()); + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager(), new StubAsyncTokenProvider()); var testFeature = extensionManager.AvailableExtensions() .SelectMany(x => x.Features); @@ -346,7 +347,7 @@ Features: Description: Contains the Phi type. "); - IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager()); + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager(), new StubAsyncTokenProvider()); var testFeature = extensionManager.AvailableExtensions() .SelectMany(x => x.Features) .Single(x => x.Id == "TestFeature"); @@ -376,7 +377,7 @@ Features: Description: Contains the Phi type. "); - IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager()); + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager(), new StubAsyncTokenProvider()); var testFeature = extensionManager.AvailableExtensions() .SelectMany(x => x.Features) .Single(x => x.Id == "TestFeature"); @@ -404,7 +405,7 @@ Features: Description: Contains the Phi type. "); - IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager()); + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager(), new StubAsyncTokenProvider()); var testModule = extensionManager.AvailableExtensions() .SelectMany(x => x.Features) .Single(x => x.Id == "TestModule"); @@ -428,7 +429,7 @@ Version: 1.0.3 OrchardVersion: 1 "); - IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager()); + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager(), new StubAsyncTokenProvider()); var minimalisticModule = extensionManager.AvailableExtensions().Single(x => x.Id == "Minimalistic"); Assert.That(minimalisticModule.Features.Count(), Is.EqualTo(1)); @@ -464,7 +465,7 @@ Features: Dependencies: Beta "); - IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager()); + IExtensionManager extensionManager = new ExtensionManager(new[] { extensionFolder }, new[] { extensionLoader }, new StubCacheManager(), new StubAsyncTokenProvider()); var features = extensionManager.AvailableFeatures(); Assert.That(features.Aggregate("<", (a, b) => a + b.Id + "<"), Is.EqualTo(" folders, StubLoaders loader, string expectedOrder) { - var extensionManager = new ExtensionManager(folders, new[] { loader }, new StubCacheManager()); + var extensionManager = new ExtensionManager(folders, new[] { loader }, new StubCacheManager(), new StubAsyncTokenProvider()); var features = extensionManager.AvailableFeatures(); Assert.That(features.Aggregate("<", (a, b) => a + b.Id + "<"), Is.EqualTo(expectedOrder)); } diff --git a/src/Orchard.Tests/Environment/Features/FeatureManagerTests.cs b/src/Orchard.Tests/Environment/Features/FeatureManagerTests.cs index 20bc33887..fd622317c 100644 --- a/src/Orchard.Tests/Environment/Features/FeatureManagerTests.cs +++ b/src/Orchard.Tests/Environment/Features/FeatureManagerTests.cs @@ -39,6 +39,7 @@ namespace Orchard.Tests.Environment.Features { builder.RegisterType().As(); builder.RegisterType().As(); builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); diff --git a/src/Orchard.Tests/Stubs/StubCacheManager.cs b/src/Orchard.Tests/Stubs/StubCacheManager.cs index 0537ef6e0..a25790d54 100644 --- a/src/Orchard.Tests/Stubs/StubCacheManager.cs +++ b/src/Orchard.Tests/Stubs/StubCacheManager.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using Orchard.Caching; namespace Orchard.Tests.Stubs { @@ -16,4 +18,21 @@ namespace Orchard.Tests.Stubs { return _defaultCacheManager.GetCache(); } } + + public class StubAsyncTokenProvider : IAsyncTokenProvider { + public IVolatileToken GetToken(Action> task) { + var tokens = new List(); + task(tokens.Add); + return new Token(tokens); + } + public class Token : IVolatileToken { + private readonly List _tokens; + + public Token(List tokens) { + _tokens = tokens; + } + + public bool IsCurrent { get { return _tokens.All(t => t.IsCurrent); } } + } + } } diff --git a/src/Orchard/Caching/DefaultAsyncTokenProvider.cs b/src/Orchard/Caching/DefaultAsyncTokenProvider.cs new file mode 100644 index 000000000..9bf8e9918 --- /dev/null +++ b/src/Orchard/Caching/DefaultAsyncTokenProvider.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using Orchard.Logging; + +namespace Orchard.Caching { + public class DefaultAsyncTokenProvider : IAsyncTokenProvider { + public DefaultAsyncTokenProvider() { + Logger = NullLogger.Instance; + } + + public ILogger Logger { get; set; } + + public IVolatileToken GetToken(Action> task) { + var token = new AsyncVolativeToken(task, Logger); + token.QueueWorkItem(); + return token; + } + + public class AsyncVolativeToken : IVolatileToken { + private readonly Action> _task; + private readonly List _taskTokens = new List(); + private volatile Exception _taskException; + private volatile bool _isTaskFinished; + + public AsyncVolativeToken(Action> task, ILogger logger) { + _task = task; + Logger = logger; + } + + public ILogger Logger { get; set; } + + public void QueueWorkItem() { + // Start a work item to collect tokens in our internal array + ThreadPool.QueueUserWorkItem((state) => { + try { + _task(token => _taskTokens.Add(token)); + } + catch (Exception e) { + Logger.Error(e, "Error while monitoring extension files. Assuming extensions are not current."); + _taskException = e; + } + finally { + _isTaskFinished = true; + } + }); + } + + public bool IsCurrent { + get { + // We are current until the task has finished + if (_taskException != null) { + return false; + } + if (_isTaskFinished) { + return _taskTokens.All(t => t.IsCurrent); + } + return true; + } + } + } + } +} \ No newline at end of file diff --git a/src/Orchard/Caching/IAsyncTokenProvider.cs b/src/Orchard/Caching/IAsyncTokenProvider.cs new file mode 100644 index 000000000..efea7b80e --- /dev/null +++ b/src/Orchard/Caching/IAsyncTokenProvider.cs @@ -0,0 +1,7 @@ +using System; + +namespace Orchard.Caching { + public interface IAsyncTokenProvider { + IVolatileToken GetToken(Action> task); + } +} \ No newline at end of file diff --git a/src/Orchard/Environment/Extensions/ExtensionManager.cs b/src/Orchard/Environment/Extensions/ExtensionManager.cs index 19e80c12b..d16c0b8f6 100644 --- a/src/Orchard/Environment/Extensions/ExtensionManager.cs +++ b/src/Orchard/Environment/Extensions/ExtensionManager.cs @@ -13,14 +13,21 @@ using Orchard.Utility.Extensions; namespace Orchard.Environment.Extensions { public class ExtensionManager : IExtensionManager { private readonly IEnumerable _folders; + private readonly IAsyncTokenProvider _asyncTokenProvider; private readonly ICacheManager _cacheManager; private readonly IEnumerable _loaders; public Localizer T { get; set; } public ILogger Logger { get; set; } - public ExtensionManager(IEnumerable folders, IEnumerable loaders, ICacheManager cacheManager) { + public ExtensionManager( + IEnumerable folders, + IEnumerable loaders, + ICacheManager cacheManager, + IAsyncTokenProvider asyncTokenProvider) { + _folders = folders; + _asyncTokenProvider = asyncTokenProvider; _cacheManager = cacheManager; _loaders = loaders.OrderBy(x => x.Order).ToArray(); T = NullLocalizer.Instance; @@ -38,7 +45,7 @@ namespace Orchard.Environment.Extensions { } public IEnumerable AvailableFeatures() { - return _cacheManager.Get("...", ctx => + return _cacheManager.Get("...", ctx => AvailableExtensions().SelectMany(ext => ext.Features).OrderByDependenciesAndPriorities(HasDependency, GetPriority).ToReadOnlyCollection()); } @@ -58,7 +65,7 @@ namespace Orchard.Environment.Extensions { // Themes implicitly depend on modules to ensure build and override ordering return true; } - + if (DefaultExtensionTypes.IsTheme(subject.Extension.ExtensionType)) { // Theme depends on another if it is its base theme return item.Extension.BaseTheme == subject.Id; @@ -91,9 +98,11 @@ namespace Orchard.Environment.Extensions { extensionEntry = _cacheManager.Get(extensionId, ctx => { var entry = BuildEntry(extensionDescriptor); if (entry != null) { - foreach (var loader in _loaders) { - loader.Monitor(entry.Descriptor, (token) => ctx.Monitor(token)); - } + ctx.Monitor(_asyncTokenProvider.GetToken(monitor => { + foreach (var loader in _loaders) { + loader.Monitor(entry.Descriptor, token => monitor(token)); + } + })); } return entry; }); @@ -134,7 +143,7 @@ namespace Orchard.Environment.Extensions { } return extensionId; } - + private ExtensionEntry BuildEntry(ExtensionDescriptor descriptor) { foreach (var loader in _loaders) { ExtensionEntry entry = loader.Load(descriptor); diff --git a/src/Orchard/Environment/Extensions/ExtensionMonitoringCoordinator.cs b/src/Orchard/Environment/Extensions/ExtensionMonitoringCoordinator.cs index e66bf1191..de139fd87 100644 --- a/src/Orchard/Environment/Extensions/ExtensionMonitoringCoordinator.cs +++ b/src/Orchard/Environment/Extensions/ExtensionMonitoringCoordinator.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading; using Orchard.Caching; using Orchard.Environment.Extensions.Loaders; using Orchard.Environment.Extensions.Models; @@ -11,14 +10,18 @@ using Orchard.Logging; namespace Orchard.Environment.Extensions { public class ExtensionMonitoringCoordinator : IExtensionMonitoringCoordinator { private readonly IVirtualPathMonitor _virtualPathMonitor; + private readonly IAsyncTokenProvider _asyncTokenProvider; private readonly IExtensionManager _extensionManager; private readonly IEnumerable _loaders; - public ExtensionMonitoringCoordinator(IVirtualPathMonitor virtualPathMonitor, + public ExtensionMonitoringCoordinator( + IVirtualPathMonitor virtualPathMonitor, + IAsyncTokenProvider asyncTokenProvider, IExtensionManager extensionManager, IEnumerable loaders) { _virtualPathMonitor = virtualPathMonitor; + _asyncTokenProvider = asyncTokenProvider; _extensionManager = extensionManager; _loaders = loaders; @@ -33,11 +36,8 @@ namespace Orchard.Environment.Extensions { if (Disabled) return; - //PREF: Monitor extensions asynchronously. IsCurrent will be 'true' - // until all tokens are collected by the work function. - var token = new AsyncVolativeToken(MonitorExtensionsWork, Logger); - monitor(token); - token.QueueWorkItem(); + //PERF: Monitor extensions asynchronously. + monitor(_asyncTokenProvider.GetToken(MonitorExtensionsWork)); } public void MonitorExtensionsWork(Action monitor) { @@ -55,48 +55,5 @@ namespace Orchard.Environment.Extensions { } Logger.Information("Done monitoring extension files..."); } - - public class AsyncVolativeToken : IVolatileToken { - private readonly Action> _task; - private readonly List _taskTokens = new List(); - private volatile Exception _taskException; - private volatile bool _isTaskFinished; - - public AsyncVolativeToken(Action> task, ILogger logger) { - _task = task; - Logger = logger; - } - - public ILogger Logger { get; set; } - - public void QueueWorkItem() { - // Start a work item to collect tokens in our internal array - ThreadPool.QueueUserWorkItem((state) => { - try { - _task(token => _taskTokens.Add(token)); - } - catch (Exception e) { - Logger.Error(e, "Error while monitoring extension files. Assuming extensions are not current."); - _taskException = e; - } - finally { - _isTaskFinished = true; - } - }); - } - - public bool IsCurrent { - get { - // We are current until the task has finished - if (_taskException != null) { - return false; - } - if (_isTaskFinished) { - return _taskTokens.All(t => t.IsCurrent); - } - return true; - } - } - } } } \ No newline at end of file diff --git a/src/Orchard/Environment/OrchardStarter.cs b/src/Orchard/Environment/OrchardStarter.cs index 6e94ae1bf..0078986a5 100644 --- a/src/Orchard/Environment/OrchardStarter.cs +++ b/src/Orchard/Environment/OrchardStarter.cs @@ -39,6 +39,7 @@ namespace Orchard.Environment { // a single default host implementation is needed for bootstrapping a web app domain builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); + builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index 885e238a8..0adf5fcb3 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -175,7 +175,9 @@ + +