From 82c25608227626fb1b162d38085982687e66def0 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Wed, 23 Jan 2013 18:40:40 +0300 Subject: [PATCH] Ensures all resolvers are sealed. Changes CacheRefreshersResolver, DataTypesResolver, MacroFieldEditorsResolver, PackageActionsResolver, ActionsResolver to all be lazy resolvers as they are not needed instantly on app startup (not needed by the front-end) This will make app startup a lot quicker. Fixes ActionsResolver to not use the PluginManager to resolve the types when it is instantiating them since these are passed in the ctor. Updates all unit tests to use lazy delegate for these resolvers and they are all passing. --- src/Umbraco.Core/ActionsResolver.cs | 8 ++++---- src/Umbraco.Core/CacheRefreshersResolver.cs | 2 +- src/Umbraco.Core/CoreBootManager.cs | 10 +++++----- src/Umbraco.Core/DataTypesResolver.cs | 2 +- .../Dictionary/CultureDictionaryFactoryResolver.cs | 2 +- .../ObjectResolution/LazyManyObjectsResolverbase.cs | 4 +++- .../LegacyTransientObjectsResolver.cs | 13 ++++++------- .../ObjectResolution/MacroFieldEditorsResolver.cs | 4 ++-- .../ObjectResolution/ManyObjectsResolverBase.cs | 11 +---------- src/Umbraco.Core/PackageActionsResolver.cs | 4 ++-- .../PropertyEditorValueConvertersResolver.cs | 2 +- src/Umbraco.Tests/CacheRefresherFactoryTests.cs | 2 +- src/Umbraco.Tests/DataTypeFactoryTests.cs | 2 +- src/Umbraco.Tests/Resolvers/ActionsResolverTests.cs | 2 +- .../Resolvers/MacroFieldEditorsResolverTests.cs | 2 +- .../Resolvers/PackageActionsResolverTests.cs | 2 +- src/Umbraco.Web/Mvc/SurfaceControllerResolver.cs | 2 +- src/Umbraco.Web/PublishedContentStoreResolver.cs | 2 +- src/Umbraco.Web/PublishedMediaStoreResolver.cs | 2 +- src/umbraco.cms/Actions/Action.cs | 2 +- 20 files changed, 36 insertions(+), 44 deletions(-) diff --git a/src/Umbraco.Core/ActionsResolver.cs b/src/Umbraco.Core/ActionsResolver.cs index cae5a4575f..083704d3bd 100644 --- a/src/Umbraco.Core/ActionsResolver.cs +++ b/src/Umbraco.Core/ActionsResolver.cs @@ -9,14 +9,14 @@ namespace Umbraco.Core /// /// A resolver to return all IAction objects /// - internal sealed class ActionsResolver : ManyObjectsResolverBase + internal sealed class ActionsResolver : LazyManyObjectsResolverBase { /// /// Constructor /// /// - internal ActionsResolver(IEnumerable packageActions) + internal ActionsResolver(Func> packageActions) : base(packageActions) { @@ -34,9 +34,9 @@ namespace Umbraco.Core } protected override IEnumerable CreateInstances() - { + { var actions = new List(); - var foundIActions = PluginManager.Current.ResolveActions(); + var foundIActions = InstanceTypes; foreach (var type in foundIActions) { IAction typeInstance; diff --git a/src/Umbraco.Core/CacheRefreshersResolver.cs b/src/Umbraco.Core/CacheRefreshersResolver.cs index 31ed877e97..51c6cfc183 100644 --- a/src/Umbraco.Core/CacheRefreshersResolver.cs +++ b/src/Umbraco.Core/CacheRefreshersResolver.cs @@ -17,7 +17,7 @@ namespace Umbraco.Core /// Constructor /// /// - internal CacheRefreshersResolver(IEnumerable refreshers) + internal CacheRefreshersResolver(Func> refreshers) : base(refreshers) { diff --git a/src/Umbraco.Core/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs index 98531f74ea..3042c962e4 100644 --- a/src/Umbraco.Core/CoreBootManager.cs +++ b/src/Umbraco.Core/CoreBootManager.cs @@ -94,19 +94,19 @@ namespace Umbraco.Core protected virtual void InitializeResolvers() { CacheRefreshersResolver.Current = new CacheRefreshersResolver( - PluginManager.Current.ResolveCacheRefreshers()); + () => PluginManager.Current.ResolveCacheRefreshers()); DataTypesResolver.Current = new DataTypesResolver( - PluginManager.Current.ResolveDataTypes()); + () => PluginManager.Current.ResolveDataTypes()); MacroFieldEditorsResolver.Current = new MacroFieldEditorsResolver( - PluginManager.Current.ResolveMacroRenderings()); + () => PluginManager.Current.ResolveMacroRenderings()); PackageActionsResolver.Current = new PackageActionsResolver( - PluginManager.Current.ResolvePackageActions()); + () => PluginManager.Current.ResolvePackageActions()); ActionsResolver.Current = new ActionsResolver( - PluginManager.Current.ResolveActions()); + () => PluginManager.Current.ResolveActions()); PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver( PluginManager.Current.ResolvePropertyEditorValueConverters()); diff --git a/src/Umbraco.Core/DataTypesResolver.cs b/src/Umbraco.Core/DataTypesResolver.cs index 024fecc1ee..65591bd917 100644 --- a/src/Umbraco.Core/DataTypesResolver.cs +++ b/src/Umbraco.Core/DataTypesResolver.cs @@ -16,7 +16,7 @@ namespace Umbraco.Core /// Constructor /// /// - internal DataTypesResolver(IEnumerable dataTypes) + internal DataTypesResolver(Func> dataTypes) : base(dataTypes) { diff --git a/src/Umbraco.Core/Dictionary/CultureDictionaryFactoryResolver.cs b/src/Umbraco.Core/Dictionary/CultureDictionaryFactoryResolver.cs index 1d754e1970..2dd7881e08 100644 --- a/src/Umbraco.Core/Dictionary/CultureDictionaryFactoryResolver.cs +++ b/src/Umbraco.Core/Dictionary/CultureDictionaryFactoryResolver.cs @@ -5,7 +5,7 @@ namespace Umbraco.Core.Dictionary /// /// Resolves the current CultureDictionaryFactory /// - internal class CultureDictionaryFactoryResolver : SingleObjectResolverBase + internal sealed class CultureDictionaryFactoryResolver : SingleObjectResolverBase { internal CultureDictionaryFactoryResolver(ICultureDictionaryFactory factory) : base(factory) diff --git a/src/Umbraco.Core/ObjectResolution/LazyManyObjectsResolverbase.cs b/src/Umbraco.Core/ObjectResolution/LazyManyObjectsResolverbase.cs index 0cd5705aa5..21374a48f5 100644 --- a/src/Umbraco.Core/ObjectResolution/LazyManyObjectsResolverbase.cs +++ b/src/Umbraco.Core/ObjectResolution/LazyManyObjectsResolverbase.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Web; namespace Umbraco.Core.ObjectResolution @@ -83,6 +84,7 @@ namespace Umbraco.Core.ObjectResolution private readonly List> _lazyTypeList = new List>(); private readonly List>> _listOfTypeListDelegates = new List>>(); private List _resolvedTypes = null; + private readonly ReaderWriterLockSlim _typeResolutionLock = new ReaderWriterLockSlim(); /// /// Used for unit tests @@ -99,7 +101,7 @@ namespace Umbraco.Core.ObjectResolution { get { - using (var lck = GetUpgradeableReadLock()) + using (var lck = new UpgradeableReadLock(_typeResolutionLock)) { var lazyTypeList = _lazyTypeList.Select(x => x.Value).ToArray(); var listofTypeListDelegates = _listOfTypeListDelegates.SelectMany(x => x()).ToArray(); diff --git a/src/Umbraco.Core/ObjectResolution/LegacyTransientObjectsResolver.cs b/src/Umbraco.Core/ObjectResolution/LegacyTransientObjectsResolver.cs index f45e7fa9df..18d67f3b41 100644 --- a/src/Umbraco.Core/ObjectResolution/LegacyTransientObjectsResolver.cs +++ b/src/Umbraco.Core/ObjectResolution/LegacyTransientObjectsResolver.cs @@ -17,7 +17,7 @@ namespace Umbraco.Core.ObjectResolution /// these old classes don't contain metadata, the objects need to be instantiated first to get their metadata, we then store this /// for use in the GetById method. /// - internal abstract class LegacyTransientObjectsResolver : ManyObjectsResolverBase + internal abstract class LegacyTransientObjectsResolver : LazyManyObjectsResolverBase where TResolved : class where TResolver : class { @@ -27,16 +27,15 @@ namespace Umbraco.Core.ObjectResolution /// /// Constructor /// - /// + /// /// /// We are creating Transient instances (new instances each time) because this is how the legacy code worked and /// I don't want to muck anything up by changing them to application based instances. /// TODO: However, it would make much more sense to do this and would speed up the application plus this would make the GetById method much easier. /// - protected LegacyTransientObjectsResolver(IEnumerable refreshers) - : base(ObjectLifetimeScope.Transient) // new objects every time - { - AddTypes(refreshers); + protected LegacyTransientObjectsResolver(Func> types) + : base(types, ObjectLifetimeScope.Transient) // new objects every time + { } #endregion @@ -55,7 +54,7 @@ namespace Umbraco.Core.ObjectResolution protected abstract Guid GetUniqueIdentifier(TResolved obj); /// - /// Returns a new ICacheRefresher instance by id + /// Returns a new TResolved instance by id /// /// /// diff --git a/src/Umbraco.Core/ObjectResolution/MacroFieldEditorsResolver.cs b/src/Umbraco.Core/ObjectResolution/MacroFieldEditorsResolver.cs index 9143e39f90..f0b6867a38 100644 --- a/src/Umbraco.Core/ObjectResolution/MacroFieldEditorsResolver.cs +++ b/src/Umbraco.Core/ObjectResolution/MacroFieldEditorsResolver.cs @@ -15,14 +15,14 @@ namespace Umbraco.Core.ObjectResolution /// Much of this classes methods are based on legacy code from umbraco.editorControls.macrocontainer.MacroControlFactory /// this code should probably be reviewed and cleaned up if necessary. /// - internal sealed class MacroFieldEditorsResolver : ManyObjectsResolverBase + internal sealed class MacroFieldEditorsResolver : LazyManyObjectsResolverBase { /// /// Constructor /// /// - internal MacroFieldEditorsResolver(IEnumerable macroEditors) + internal MacroFieldEditorsResolver(Func> macroEditors) : base(macroEditors, ObjectLifetimeScope.Transient) { diff --git a/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs b/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs index c2fb584602..9343b1a58b 100644 --- a/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs +++ b/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs @@ -320,16 +320,7 @@ namespace Umbraco.Core.ObjectResolution { return new WriteLock(_lock); } - - /// - /// Returns an upgradeable read lock for use when reading/modifying collections - /// - /// - protected UpgradeableReadLock GetUpgradeableReadLock() - { - return new UpgradeableReadLock(_lock); - } - + /// /// Throws an exception if resolution is frozen /// diff --git a/src/Umbraco.Core/PackageActionsResolver.cs b/src/Umbraco.Core/PackageActionsResolver.cs index 8c1d412374..551bf8cfa7 100644 --- a/src/Umbraco.Core/PackageActionsResolver.cs +++ b/src/Umbraco.Core/PackageActionsResolver.cs @@ -8,14 +8,14 @@ namespace Umbraco.Core /// /// A resolver to return all IPackageAction objects /// - internal sealed class PackageActionsResolver : ManyObjectsResolverBase + internal sealed class PackageActionsResolver : LazyManyObjectsResolverBase { /// /// Constructor /// /// - internal PackageActionsResolver(IEnumerable packageActions) + internal PackageActionsResolver(Func> packageActions) : base(packageActions) { diff --git a/src/Umbraco.Core/PropertyEditors/PropertyEditorValueConvertersResolver.cs b/src/Umbraco.Core/PropertyEditors/PropertyEditorValueConvertersResolver.cs index aaf1c06102..f804f424a6 100644 --- a/src/Umbraco.Core/PropertyEditors/PropertyEditorValueConvertersResolver.cs +++ b/src/Umbraco.Core/PropertyEditors/PropertyEditorValueConvertersResolver.cs @@ -7,7 +7,7 @@ namespace Umbraco.Core.PropertyEditors /// /// Manages the list of IPropertyEditorValueConverter's /// - internal class PropertyEditorValueConvertersResolver : ManyObjectsResolverBase + internal sealed class PropertyEditorValueConvertersResolver : ManyObjectsResolverBase { public PropertyEditorValueConvertersResolver(IEnumerable converters) : base(converters) diff --git a/src/Umbraco.Tests/CacheRefresherFactoryTests.cs b/src/Umbraco.Tests/CacheRefresherFactoryTests.cs index 8fdef3f09a..782638a1db 100644 --- a/src/Umbraco.Tests/CacheRefresherFactoryTests.cs +++ b/src/Umbraco.Tests/CacheRefresherFactoryTests.cs @@ -26,7 +26,7 @@ namespace Umbraco.Tests }; CacheRefreshersResolver.Current = new CacheRefreshersResolver( - PluginManager.Current.ResolveCacheRefreshers()); + () => PluginManager.Current.ResolveCacheRefreshers()); Resolution.Freeze(); } diff --git a/src/Umbraco.Tests/DataTypeFactoryTests.cs b/src/Umbraco.Tests/DataTypeFactoryTests.cs index e0de0a4af6..fadc45a843 100644 --- a/src/Umbraco.Tests/DataTypeFactoryTests.cs +++ b/src/Umbraco.Tests/DataTypeFactoryTests.cs @@ -28,7 +28,7 @@ namespace Umbraco.Tests }; DataTypesResolver.Current = new DataTypesResolver( - PluginManager.Current.ResolveDataTypes()); + () => PluginManager.Current.ResolveDataTypes()); Resolution.Freeze(); } diff --git a/src/Umbraco.Tests/Resolvers/ActionsResolverTests.cs b/src/Umbraco.Tests/Resolvers/ActionsResolverTests.cs index 34b834753b..391b0c6072 100644 --- a/src/Umbraco.Tests/Resolvers/ActionsResolverTests.cs +++ b/src/Umbraco.Tests/Resolvers/ActionsResolverTests.cs @@ -27,7 +27,7 @@ namespace Umbraco.Tests.Resolvers }; ActionsResolver.Current = new ActionsResolver( - PluginManager.Current.ResolveActions()); + () => PluginManager.Current.ResolveActions()); Resolution.Freeze(); } diff --git a/src/Umbraco.Tests/Resolvers/MacroFieldEditorsResolverTests.cs b/src/Umbraco.Tests/Resolvers/MacroFieldEditorsResolverTests.cs index 6f7ae14ce9..5507400091 100644 --- a/src/Umbraco.Tests/Resolvers/MacroFieldEditorsResolverTests.cs +++ b/src/Umbraco.Tests/Resolvers/MacroFieldEditorsResolverTests.cs @@ -27,7 +27,7 @@ namespace Umbraco.Tests.Resolvers }; MacroFieldEditorsResolver.Current = new MacroFieldEditorsResolver( - PluginManager.Current.ResolveMacroRenderings()); + () => PluginManager.Current.ResolveMacroRenderings()); Resolution.Freeze(); } diff --git a/src/Umbraco.Tests/Resolvers/PackageActionsResolverTests.cs b/src/Umbraco.Tests/Resolvers/PackageActionsResolverTests.cs index a12890a36f..b7b9d0a6fe 100644 --- a/src/Umbraco.Tests/Resolvers/PackageActionsResolverTests.cs +++ b/src/Umbraco.Tests/Resolvers/PackageActionsResolverTests.cs @@ -27,7 +27,7 @@ namespace Umbraco.Tests.Resolvers }; PackageActionsResolver.Current = new PackageActionsResolver( - PluginManager.Current.ResolvePackageActions()); + () => PluginManager.Current.ResolvePackageActions()); Resolution.Freeze(); } diff --git a/src/Umbraco.Web/Mvc/SurfaceControllerResolver.cs b/src/Umbraco.Web/Mvc/SurfaceControllerResolver.cs index e9e60e1c58..31176d282c 100644 --- a/src/Umbraco.Web/Mvc/SurfaceControllerResolver.cs +++ b/src/Umbraco.Web/Mvc/SurfaceControllerResolver.cs @@ -4,7 +4,7 @@ using Umbraco.Core.ObjectResolution; namespace Umbraco.Web.Mvc { - internal class SurfaceControllerResolver : ManyObjectsResolverBase + internal sealed class SurfaceControllerResolver : ManyObjectsResolverBase { public SurfaceControllerResolver(IEnumerable surfaceControllers) : base(surfaceControllers) diff --git a/src/Umbraco.Web/PublishedContentStoreResolver.cs b/src/Umbraco.Web/PublishedContentStoreResolver.cs index 0e0f049443..2ba6eb0ef1 100644 --- a/src/Umbraco.Web/PublishedContentStoreResolver.cs +++ b/src/Umbraco.Web/PublishedContentStoreResolver.cs @@ -5,7 +5,7 @@ namespace Umbraco.Web /// /// An object resolver to return the IPublishedContentStore /// - internal class PublishedContentStoreResolver : SingleObjectResolverBase + internal sealed class PublishedContentStoreResolver : SingleObjectResolverBase { internal PublishedContentStoreResolver(IPublishedContentStore publishedContentStore) : base(publishedContentStore) diff --git a/src/Umbraco.Web/PublishedMediaStoreResolver.cs b/src/Umbraco.Web/PublishedMediaStoreResolver.cs index e3a7dc3bac..6f741b3796 100644 --- a/src/Umbraco.Web/PublishedMediaStoreResolver.cs +++ b/src/Umbraco.Web/PublishedMediaStoreResolver.cs @@ -5,7 +5,7 @@ namespace Umbraco.Web /// /// An object resolver to return the IPublishedMediaStore /// - internal class PublishedMediaStoreResolver : SingleObjectResolverBase + internal sealed class PublishedMediaStoreResolver : SingleObjectResolverBase { internal PublishedMediaStoreResolver(IPublishedMediaStore publishedMediaStore) : base(publishedMediaStore) diff --git a/src/umbraco.cms/Actions/Action.cs b/src/umbraco.cms/Actions/Action.cs index 34ff982eb2..4a1dd6e808 100644 --- a/src/umbraco.cms/Actions/Action.cs +++ b/src/umbraco.cms/Actions/Action.cs @@ -59,7 +59,7 @@ namespace umbraco.BusinessLogic.Actions //TODO: Based on the above, this is a big hack as types should all be cleared on package install! ActionsResolver.Current = new ActionsResolver( - TypeFinder.FindClassesOfType(PluginManager.Current.AssembliesToScan)); + () => TypeFinder.FindClassesOfType(PluginManager.Current.AssembliesToScan)); RegisterIActionHandlers(); }