diff --git a/src/Umbraco.Core/PluginTypeResolver.cs b/src/Umbraco.Core/PluginTypeResolver.cs index 9255eac146..d6d46ef3f3 100644 --- a/src/Umbraco.Core/PluginTypeResolver.cs +++ b/src/Umbraco.Core/PluginTypeResolver.cs @@ -125,7 +125,7 @@ namespace Umbraco.Core return instances.FirstOrDefault(); } - private IEnumerable ResolveTypes(Func> finder) + private IEnumerable ResolveTypes(Func> finder, bool typeIsAttribute = false) { using (var readLock = new UpgradeableReadLock(_lock)) { @@ -140,7 +140,7 @@ namespace Umbraco.Core //upgrade to a write lock since we're adding to the collection readLock.UpgradeToWriteLock(); - typeList = new TypeList(); + typeList = new TypeList(typeIsAttribute); foreach (var t in finder()) { @@ -185,7 +185,9 @@ namespace Umbraco.Core internal IEnumerable ResolveAttributedTypes() where TAttribute : Attribute { - return ResolveTypes(() => TypeFinder.FindClassesWithAttribute(AssembliesToScan)); + return ResolveTypes( + () => TypeFinder.FindClassesWithAttribute(AssembliesToScan), + true); } /// @@ -209,11 +211,20 @@ namespace Umbraco.Core internal class TypeList : TypeList { + private readonly bool _typeIsAttribute; + + public TypeList(bool typeIsAttribute = false) + { + _typeIsAttribute = typeIsAttribute; + } + private readonly List _types = new List(); public override void AddType(Type t) { - if (t.IsType()) + + //if the type is an attribute type we won't do the type check + if (_typeIsAttribute || t.IsType()) { _types.Add(t); } diff --git a/src/Umbraco.Tests/PluginTypeResolverTests.cs b/src/Umbraco.Tests/PluginTypeResolverTests.cs index c071b956c9..37f3eb00d1 100644 --- a/src/Umbraco.Tests/PluginTypeResolverTests.cs +++ b/src/Umbraco.Tests/PluginTypeResolverTests.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using SqlCE4Umbraco; using Umbraco.Core; using Umbraco.Web; +using umbraco; using umbraco.DataLayer; using umbraco.MacroEngines; using umbraco.MacroEngines.Iron; @@ -111,8 +112,21 @@ namespace Umbraco.Tests Assert.AreEqual(1, types.Count()); } + [Test] + public void Resolves_XsltExtensions() + { + var types = PluginTypeResolver.Current.ResolveXsltExtensions(); + Assert.AreEqual(1, types.Count()); + } + + [XsltExtension("Blah.Blah")] + public class MyXsltExtension + { + + } + [RestExtension("Blah")] - public class MyTestExtension + public class MyRestExtension { } diff --git a/src/Umbraco.Web/PluginTypeResolverExtensions.cs b/src/Umbraco.Web/PluginTypeResolverExtensions.cs index 0a3b4b4a09..4e536dd6e9 100644 --- a/src/Umbraco.Web/PluginTypeResolverExtensions.cs +++ b/src/Umbraco.Web/PluginTypeResolverExtensions.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Threading; using Umbraco.Core; using Umbraco.Web.Routing; +using umbraco; using umbraco.interfaces; using umbraco.presentation.umbracobase; @@ -33,5 +34,15 @@ namespace Umbraco.Web { return resolver.ResolveAttributedTypes(); } + + /// + /// Returns all classes attributed with XsltExtensionAttribute attribute + /// + /// + /// + internal static IEnumerable ResolveXsltExtensions(this PluginTypeResolver resolver) + { + return resolver.ResolveAttributedTypes(); + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index fbc82bc396..b0138fcf64 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -16,6 +16,7 @@ using System.Web.UI; using System.Web.UI.WebControls; using System.Xml; using System.Xml.Xsl; +using Umbraco.Core; using umbraco.BusinessLogic; using umbraco.BusinessLogic.Utils; using umbraco.cms.businesslogic.macro; @@ -775,6 +776,10 @@ namespace umbraco // We could cache the extensions in a static variable but then the cache // would not be refreshed when the .config file is modified. An application // restart would be required. Better use the cache and add a dependency. + + // SD: Not sure what is meant by the above statement? Having these in a static variable would be preferred! + // If you modify a config file, the app restarts and thus all static variables are reset. + // Having this stuff in cache just adds to the gigantic amount of cache data and will cause more cache turnover to happen. return cms.businesslogic.cache.Cache.GetCacheItem( _xsltExtensionsCacheKey, _xsltExtensionsSyncLock, @@ -782,7 +787,7 @@ namespace umbraco null, // no refresh action _xsltExtensionsDependency.Value, // depends on the .config file TimeSpan.FromDays(1), // expires in 1 day (?) - () => { return GetXsltExtensionsImpl(); }); + GetXsltExtensionsImpl); } // zb-00041 #29966 : cache the extensions @@ -840,13 +845,16 @@ namespace umbraco //also get types marked with XsltExtension attribute // zb-00042 #29949 : do not hide errors, refactor - var typeFinder = new Umbraco.Core.TypeFinder2(); - foreach (var xsltType in typeFinder.FindClassesWithAttribute()) + + var foundExtensions = Umbraco.Web.PluginTypeResolverExtensions.ResolveXsltExtensions(PluginTypeResolver.Current); + foreach (var xsltType in foundExtensions) { - object[] tpAttributes = xsltType.GetCustomAttributes(typeof(XsltExtensionAttribute), true); + var tpAttributes = xsltType.GetCustomAttributes(typeof(XsltExtensionAttribute), true); foreach (XsltExtensionAttribute tpAttribute in tpAttributes) { - string ns = !string.IsNullOrEmpty(tpAttribute.Namespace) ? tpAttribute.Namespace : xsltType.FullName; + var ns = !string.IsNullOrEmpty(tpAttribute.Namespace) + ? tpAttribute.Namespace + : xsltType.FullName; extensions.Add(ns, Activator.CreateInstance(xsltType)); } }