diff --git a/src/Umbraco.Core/PluginManager.cs b/src/Umbraco.Core/PluginManager.cs index 2d00d19ee2..22d8f5bb5c 100644 --- a/src/Umbraco.Core/PluginManager.cs +++ b/src/Umbraco.Core/PluginManager.cs @@ -309,7 +309,7 @@ namespace Umbraco.Core //return false but specify this exception type so we can detect it if (typeElement == null) - return Attempt>.Fail(new CachedPluginNotFoundInFile()); + return Attempt>.Fail(new CachedPluginNotFoundInFileException()); //return success return Attempt.Succeed(typeElement.Elements("add") @@ -671,8 +671,15 @@ namespace Umbraco.Core { //check if the TypeList already exists, if so return it, if not we'll create it var typeList = _types.SingleOrDefault(x => x.IsTypeList(resolutionType)); + + //need to put some logging here to try to figure out why this is happening: http://issues.umbraco.org/issue/U4-3505 + if (cacheResult && typeList != null) + { + LogHelper.Debug("Existing typeList found for {0} with resolution type {1}", () => typeof(T), () => resolutionType); + } + //if we're not caching the result then proceed, or if the type list doesn't exist then proceed - if (!cacheResult || typeList == null) + if (cacheResult == false || typeList == null) { //upgrade to a write lock since we're adding to the collection readLock.UpgradeToWriteLock(); @@ -681,15 +688,17 @@ namespace Umbraco.Core //we first need to look into our cache file (this has nothing to do with the 'cacheResult' parameter which caches in memory). //if assemblies have not changed and the cache file actually exists, then proceed to try to lookup by the cache file. - if (!HaveAssembliesChanged && File.Exists(GetPluginListFilePath())) + if (HaveAssembliesChanged == false && File.Exists(GetPluginListFilePath())) { var fileCacheResult = TryGetCachedPluginsFromFile(resolutionType); //here we need to identify if the CachedPluginNotFoundInFile was the exception, if it was then we need to re-scan //in some cases the plugin will not have been scanned for on application startup, but the assemblies haven't changed //so in this instance there will never be a result. - if (fileCacheResult.Exception != null && fileCacheResult.Exception is CachedPluginNotFoundInFile) + if (fileCacheResult.Exception != null && fileCacheResult.Exception is CachedPluginNotFoundInFileException) { + LogHelper.Debug("Tried to find typelist for type {0} and resolution {1} in file cache but the type was not found so loading types by assembly scan ", () => typeof(T), () => resolutionType); + //we don't have a cache for this so proceed to look them up by scanning LoadViaScanningAndUpdateCacheFile(typeList, resolutionType, finder); } @@ -717,20 +726,22 @@ namespace Umbraco.Core break; } } - if (!successfullyLoadedFromCache) + if (successfullyLoadedFromCache == false) { //we need to manually load by scanning if loading from the file was not successful. LoadViaScanningAndUpdateCacheFile(typeList, resolutionType, finder); } else { - LogHelper.Debug("Loaded plugin types " + typeof(T).FullName + " from persisted cache"); + LogHelper.Debug("Loaded plugin types {0} with resolution {1} from persisted cache", () => typeof(T), () => resolutionType); } } } } else { + LogHelper.Debug("Assembly changes detected, loading types {0} for resolution {1} by assembly scan", () => typeof(T), () => resolutionType); + //we don't have a cache for this so proceed to look them up by scanning LoadViaScanningAndUpdateCacheFile(typeList, resolutionType, finder); } @@ -739,7 +750,10 @@ namespace Umbraco.Core if (cacheResult) { //add the type list to the collection - _types.Add(typeList); + var added = _types.Add(typeList); + + LogHelper.Debug("Caching of typelist for type {0} and resolution {1} was successful = {2}", () => typeof(T), () => resolutionType, () => added); + } } typesFound = typeList.GetTypes().ToList(); @@ -863,14 +877,14 @@ namespace Umbraco.Core } /// - /// Returns true if the current TypeList is of the same type and of the same type + /// Returns true if the current TypeList is of the same lookup type /// /// /// /// public override bool IsTypeList(TypeResolutionKind resolutionType) { - return _resolutionType == resolutionType && (typeof(T)).IsType(); + return _resolutionType == resolutionType && (typeof(T)) == typeof(TLookup); } public override IEnumerable GetTypes() @@ -883,7 +897,7 @@ namespace Umbraco.Core /// This class is used simply to determine that a plugin was not found in the cache plugin list with the specified /// TypeResolutionKind. /// - internal class CachedPluginNotFoundInFile : Exception + internal class CachedPluginNotFoundInFileException : Exception { } diff --git a/src/Umbraco.Tests/PluginManagerTests.cs b/src/Umbraco.Tests/PluginManagerTests.cs index f9f8a7f18a..ea244c06eb 100644 --- a/src/Umbraco.Tests/PluginManagerTests.cs +++ b/src/Umbraco.Tests/PluginManagerTests.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; @@ -9,8 +10,10 @@ using NUnit.Framework; using SqlCE4Umbraco; using Umbraco.Core; using Umbraco.Core.IO; +using Umbraco.Core.PropertyEditors; using Umbraco.Tests.TestHelpers; using Umbraco.Web; +using Umbraco.Web.PropertyEditors; using umbraco; using umbraco.DataLayer; using umbraco.MacroEngines; @@ -333,6 +336,29 @@ namespace Umbraco.Tests var types = PluginManager.Current.ResolveXsltExtensions(); Assert.AreEqual(3, types.Count()); } + + /// + /// This demonstrates this issue: http://issues.umbraco.org/issue/U4-3505 - the TypeList was returning a list of assignable types + /// not explicit types which is sort of ideal but is confusing so we'll do it the less confusing way. + /// + [Test] + public void TypeList_Resolves_Explicit_Types() + { + var types = new HashSet(); + + var propEditors = new PluginManager.TypeList(PluginManager.TypeResolutionKind.FindAllTypes); + propEditors.AddType(typeof (LabelPropertyEditor)); + types.Add(propEditors); + + var found = types.SingleOrDefault(x => x.IsTypeList(PluginManager.TypeResolutionKind.FindAllTypes)); + + Assert.IsNotNull(found); + + //This should not find a type list of this type + var shouldNotFind = types.SingleOrDefault(x => x.IsTypeList(PluginManager.TypeResolutionKind.FindAllTypes)); + + Assert.IsNull(shouldNotFind); + } [XsltExtension("Blah.Blah")] public class MyXsltExtension