From 15c5b5de576e28b987344cc88909c1f4c5c6926b Mon Sep 17 00:00:00 2001 From: "shannon@ShandemVaio" Date: Thu, 26 Jul 2012 22:19:08 +0600 Subject: [PATCH] Moved type helper methods from TypeFinder2 to TypeHelper. Created SystemUtilities for detecting app trust levels. Updated all calls to TypeFinder to TypeFinder2 and updated tests. --- src/Umbraco.Core/SystemUtilities.cs | 40 ++++ src/Umbraco.Core/TypeExtensions.cs | 2 +- src/Umbraco.Core/TypeFinder2.cs | 202 ++++-------------- src/Umbraco.Core/TypeHelper.cs | 105 +++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 2 + src/Umbraco.Tests/TypeFinderBenchmarkTests.cs | 130 +++++------ src/Umbraco.Web/umbraco.presentation/macro.cs | 3 +- .../Packages/BrowseRepository.aspx.cs | 2 +- .../umbracobase/restExtension.cs | 6 +- src/umbraco.businesslogic/Utils/TypeFinder.cs | 25 +-- .../Utils/TypeResolver.cs | 4 +- 11 files changed, 252 insertions(+), 269 deletions(-) create mode 100644 src/Umbraco.Core/SystemUtilities.cs create mode 100644 src/Umbraco.Core/TypeHelper.cs diff --git a/src/Umbraco.Core/SystemUtilities.cs b/src/Umbraco.Core/SystemUtilities.cs new file mode 100644 index 0000000000..5146aade59 --- /dev/null +++ b/src/Umbraco.Core/SystemUtilities.cs @@ -0,0 +1,40 @@ +using System.Security; +using System.Web; + +namespace Umbraco.Core +{ + /// + /// Static helper methods for returning information about the current System + /// + public static class SystemUtilities + { + + /// + /// Get the current trust level of the hosted application + /// + /// + public static AspNetHostingPermissionLevel GetCurrentTrustLevel() + { + foreach (var trustLevel in new[] { + AspNetHostingPermissionLevel.Unrestricted, + AspNetHostingPermissionLevel.High, + AspNetHostingPermissionLevel.Medium, + AspNetHostingPermissionLevel.Low, + AspNetHostingPermissionLevel.Minimal }) + { + try + { + new AspNetHostingPermission(trustLevel).Demand(); + } + catch (SecurityException) + { + continue; + } + + return trustLevel; + } + + return AspNetHostingPermissionLevel.None; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/TypeExtensions.cs b/src/Umbraco.Core/TypeExtensions.cs index 21506b3b46..c4e81b2d31 100644 --- a/src/Umbraco.Core/TypeExtensions.cs +++ b/src/Umbraco.Core/TypeExtensions.cs @@ -156,7 +156,7 @@ namespace Umbraco.Core /// public static bool IsType(this Type actualType) { - return TypeFinder2.IsTypeAssignableFrom(actualType); + return TypeHelper.IsTypeAssignableFrom(actualType); } public static string GetCacheKeyFromParameters(this MemberInfo info) diff --git a/src/Umbraco.Core/TypeFinder2.cs b/src/Umbraco.Core/TypeFinder2.cs index aa888aafc1..8f9f67b4bc 100644 --- a/src/Umbraco.Core/TypeFinder2.cs +++ b/src/Umbraco.Core/TypeFinder2.cs @@ -22,21 +22,15 @@ namespace Umbraco.Core /// public class TypeFinder2 { - private static readonly ConcurrentDictionary, bool> TypeCheckCache = new ConcurrentDictionary, bool>(); - private static readonly ConcurrentDictionary ValueTypeCache = new ConcurrentDictionary(); - private static readonly ConcurrentDictionary ImplicitValueTypeCache = new ConcurrentDictionary(); - //private static readonly ConcurrentDictionary GetFieldsCache = new ConcurrentDictionary(); - //private static readonly ConcurrentDictionary, PropertyInfo[]> GetPropertiesCache = new ConcurrentDictionary, PropertyInfo[]>(); + private static readonly ConcurrentBag LocalFilteredAssemblyCache = new ConcurrentBag(); private static readonly ReaderWriterLockSlim LocalFilteredAssemblyCacheLocker = new ReaderWriterLockSlim(); /// /// Caches attributed assembly information so they don't have to be re-read /// private readonly AttributedAssemblyList _attributedAssemblies = new AttributedAssemblyList(); - private static ReadOnlyCollection _allAssemblies = null; private static ReadOnlyCollection _binFolderAssemblies = null; - private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(); /// @@ -57,6 +51,7 @@ namespace Umbraco.Core { using (new WriteLock(Locker)) { + try { var isHosted = HttpContext.Current != null; @@ -65,8 +60,7 @@ namespace Umbraco.Core { if (isHosted) { - _allAssemblies = new ReadOnlyCollection( - BuildManager.GetReferencedAssemblies().Cast().ToList()); + _allAssemblies = new ReadOnlyCollection(BuildManager.GetReferencedAssemblies().Cast().ToList()); } } catch (InvalidOperationException e) @@ -77,6 +71,9 @@ namespace Umbraco.Core _allAssemblies = _allAssemblies ?? new ReadOnlyCollection(AppDomain.CurrentDomain.GetAssemblies().ToList()); + //here we are getting just the /bin folder assemblies, we may need to use these if we implement the App_Plugins + //stuff from v5. + var codeBase = Assembly.GetExecutingAssembly().CodeBase; var uri = new Uri(codeBase); var path = uri.LocalPath; @@ -87,95 +84,54 @@ namespace Umbraco.Core var binFolderAssemblies = dllFiles.Select(AssemblyName.GetAssemblyName) .Select(assemblyName => - { - try - { - return _allAssemblies.FirstOrDefault(a => - AssemblyName.ReferenceMatchesDefinition(a.GetName(), assemblyName)); - } - catch (SecurityException) - { - return null; - } - }) + _allAssemblies.FirstOrDefault(a => + AssemblyName.ReferenceMatchesDefinition(a.GetName(), assemblyName))) .Where(locatedAssembly => locatedAssembly != null) .ToList(); _binFolderAssemblies = new ReadOnlyCollection(binFolderAssemblies); + } catch (InvalidOperationException e) { - if (e.InnerException is SecurityException) - { - // Cannot scan bin folder in medium trust - _binFolderAssemblies = _allAssemblies; - } + if (!(e.InnerException is SecurityException)) + throw; + + _binFolderAssemblies = _allAssemblies; } } } return _allAssemblies; - } - + } + /// - /// Returns all assemblies loaded in the bin folder that are not in GAC - /// - /// - internal static IEnumerable GetBinFolderAssemblies() - { - if (_binFolderAssemblies == null) GetAllAssemblies(); - return _binFolderAssemblies; - } - - /// - /// Return a list of found assemblies for the AppDomain, excluding the GAC, the ones passed in and excluding the exclusion list filter + /// Return a list of found local Assemblies excluding the known assemblies we don't want to scan + /// and exluding the ones passed in and excluding the exclusion list filter, the results of this are + /// cached for perforance reasons. /// /// /// - internal static IEnumerable GetFilteredDomainAssemblies(IEnumerable excludeFromResults = null) - { - if (excludeFromResults == null) - excludeFromResults = new List(); - - return GetLocalAssembliesWithKnownExclusions().Except(excludeFromResults); - } - - internal static IEnumerable GetLocalAssembliesWithKnownExclusions(IEnumerable excludeFromResults = null) + internal static IEnumerable GetAssembliesWithKnownExclusions( + IEnumerable excludeFromResults = null) { if (LocalFilteredAssemblyCache.Any()) return LocalFilteredAssemblyCache; using (new WriteLock(LocalFilteredAssemblyCacheLocker)) { - var assemblies = GetAllAssemblies() - .Where(x => !x.GlobalAssemblyCache - && !KnownAssemblyExclusionFilter.Any(f => x.FullName.StartsWith(f))); + var assemblies = GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter); assemblies.ForEach(LocalFilteredAssemblyCache.Add); } return LocalFilteredAssemblyCache; - } + } /// - /// Return a list of found local Assemblies in the bin folder exluding the ones passed in and excluding the exclusion list filter - /// - /// - /// - internal static IEnumerable GetFilteredBinFolderAssemblies(IEnumerable excludeFromResults = null) - { - if (excludeFromResults == null) - excludeFromResults = new List(); - - return GetBinFolderAssemblies() - .Where(x => !excludeFromResults.Contains(x) - && !x.GlobalAssemblyCache - && !KnownAssemblyExclusionFilter.Any(f => x.FullName.StartsWith(f))); - } - - /// - /// Return a list of found local Assemblies including plugins and exluding the ones passed in and excluding the exclusion list filter + /// Return a list of found local Assemblies and exluding the ones passed in and excluding the exclusion list filter /// /// /// /// - internal static IEnumerable GetFilteredLocalAssemblies(IEnumerable excludeFromResults = null, + private static IEnumerable GetFilteredAssemblies( + IEnumerable excludeFromResults = null, string[] exclusionFilter = null) { if (excludeFromResults == null) @@ -232,55 +188,9 @@ namespace Umbraco.Core "Examine." }; - /// - /// Determines whether the type is assignable from the specified implementation , - /// and caches the result across the application using a . - /// - /// The type of the contract. - /// The implementation. - public static bool IsTypeAssignableFrom(Type implementation) - { - return IsTypeAssignableFrom(typeof(TContract), implementation); - } + - /// - /// Determines whether the type is assignable from the specified implementation , - /// and caches the result across the application using a . - /// - /// The type of the contract. - /// The implementation. - /// - /// true if [is type assignable from] [the specified contract]; otherwise, false. - /// - public static bool IsTypeAssignableFrom(Type contract, Type implementation) - { - // NOTE The use of a Tuple<,> here is because its Equals / GetHashCode implementation is literally 10.5x faster than KeyValuePair<,> - return TypeCheckCache.GetOrAdd(new Tuple(contract, implementation), x => x.Item1.IsAssignableFrom(x.Item2)); - } - - /// - /// A cached method to determine whether represents a value type. - /// - /// The implementation. - public static bool IsValueType(Type implementation) - { - return ValueTypeCache.GetOrAdd(implementation, x => x.IsValueType || x.IsPrimitive); - } - - /// - /// A cached method to determine whether is an implied value type (, or a string). - /// - /// The implementation. - public static bool IsImplicitValueType(Type implementation) - { - return ImplicitValueTypeCache.GetOrAdd(implementation, x => IsValueType(implementation) || implementation.IsEnum || implementation == typeof(string)); - } - - public static bool IsTypeAssignableFrom(object implementation) - { - if (implementation == null) throw new ArgumentNullException("implementation"); - return IsTypeAssignableFrom(implementation.GetType()); - } + @@ -308,7 +218,7 @@ namespace Umbraco.Core //We must do a ToList() here because it is required to be serializable when using other app domains. return _attributedAssemblies - .Where(x => x.PluginAttributeType.Equals(typeof(T)) + .Where(x => x.PluginAttributeType == typeof(T) && assemblies.Select(y => y.FullName).Contains(x.Assembly.FullName)) .Select(x => x.Assembly) .ToList(); @@ -349,7 +259,7 @@ namespace Umbraco.Core /// public IEnumerable FindClassesOfType() { - return FindClassesOfType(GetFilteredLocalAssemblies(), true); + return FindClassesOfType(GetAssembliesWithKnownExclusions(), true); } /// @@ -441,7 +351,7 @@ namespace Umbraco.Core public IEnumerable FindClassesWithAttribute() where T : Attribute { - return FindClassesWithAttribute(GetFilteredLocalAssemblies()); + return FindClassesWithAttribute(GetAssembliesWithKnownExclusions()); } #region Internal Methods - For testing @@ -480,6 +390,10 @@ namespace Umbraco.Core #endregion #region Internal Attributed Assembly class + + //These can be removed once we implement the .hash file for caching assemblies that are found containing plugin types. + // Once that is done, remove these classes and remove the TypeFinder test: Benchmark_Finding_First_Type_In_Assemblies + private class AttributedAssembly { internal DirectoryInfo AssemblyFolder { get; set; } @@ -496,8 +410,8 @@ namespace Umbraco.Core /// internal bool IsRegistered(DirectoryInfo folder) { - return this.Where(x => x.PluginAttributeType == typeof(T) - && x.AssemblyFolder.FullName.ToUpper() == folder.FullName.ToUpper()).Any(); + return this.Any(x => x.PluginAttributeType == typeof(T) + && x.AssemblyFolder.FullName.ToUpper() == folder.FullName.ToUpper()); } /// @@ -508,9 +422,8 @@ namespace Umbraco.Core /// internal bool IsRegistered(Assembly assembly) { - return this.Where(x => x.PluginAttributeType == typeof(T) - && x.Assembly.FullName.ToUpper() == assembly.FullName.ToUpper()) - .Any(); + return this.Any(x => x.PluginAttributeType == typeof(T) + && x.Assembly.FullName.ToUpper() == assembly.FullName.ToUpper()); } } @@ -553,7 +466,7 @@ namespace Umbraco.Core { return (from a in assemblies from t in GetTypesWithFormattedException(a) - where !t.IsInterface && assignTypeFrom.IsAssignableFrom(t) && (onlyConcreteClasses ? (t.IsClass && !t.IsAbstract) : true) + where !t.IsInterface && assignTypeFrom.IsAssignableFrom(t) && (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract)) select t).ToList(); } @@ -591,7 +504,7 @@ namespace Umbraco.Core try { foreach (Type t in - assembly.GetExportedTypes().Where(t => !t.IsInterface && assignTypeFrom.IsAssignableFrom(t) && (onlyConcreteClasses ? (t.IsClass && !t.IsAbstract) : true))) + assembly.GetExportedTypes().Where(t => !t.IsInterface && assignTypeFrom.IsAssignableFrom(t) && (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract)))) { //add the full type name and full assembly name result.Add(t.FullName, t.Assembly.FullName); @@ -607,39 +520,6 @@ namespace Umbraco.Core #endregion - ///// - ///// Gets (and caches) discoverable in the current for a given . - ///// - ///// The source. - ///// - //public static FieldInfo[] CachedDiscoverableFields(Type type) - //{ - // return GetFieldsCache.GetOrAdd( - // type, - // x => type - // .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) - // .Where(y => !y.IsInitOnly) - // .ToArray()); - //} - - ///// - ///// Gets (and caches) discoverable in the current for a given . - ///// - ///// The source. - ///// true if the properties discovered are readable - ///// true if the properties discovered are writable - ///// true if the properties discovered are indexable - ///// - //public static PropertyInfo[] CachedDiscoverableProperties(Type type, bool mustRead = true, bool mustWrite = true, bool includeIndexed = false) - //{ - // return GetPropertiesCache.GetOrAdd( - // new Tuple(type, mustRead, mustWrite, includeIndexed), - // x => type - // .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) - // .Where(y => (!mustRead || y.CanRead) - // && (!mustWrite || y.CanWrite) - // && (includeIndexed || !y.GetIndexParameters().Any())) - // .ToArray()); - //} + } } diff --git a/src/Umbraco.Core/TypeHelper.cs b/src/Umbraco.Core/TypeHelper.cs new file mode 100644 index 0000000000..231c5b3b4c --- /dev/null +++ b/src/Umbraco.Core/TypeHelper.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Concurrent; +using System.Linq; +using System.Reflection; + +namespace Umbraco.Core +{ + /// + /// A utility class for type checking, this provides internal caching so that calls to these methods will be faster + /// than doing a manual type check in c# + /// + public static class TypeHelper + { + private static readonly ConcurrentDictionary, bool> TypeCheckCache = new ConcurrentDictionary, bool>(); + private static readonly ConcurrentDictionary ValueTypeCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary ImplicitValueTypeCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary GetFieldsCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary, PropertyInfo[]> GetPropertiesCache = new ConcurrentDictionary, PropertyInfo[]>(); + + /// + /// Determines whether the type is assignable from the specified implementation , + /// and caches the result across the application using a . + /// + /// The type of the contract. + /// The implementation. + /// + /// true if [is type assignable from] [the specified contract]; otherwise, false. + /// + public static bool IsTypeAssignableFrom(Type contract, Type implementation) + { + // NOTE The use of a Tuple<,> here is because its Equals / GetHashCode implementation is literally 10.5x faster than KeyValuePair<,> + return TypeCheckCache.GetOrAdd(new Tuple(contract, implementation), x => x.Item1.IsAssignableFrom(x.Item2)); + } + + /// + /// Determines whether the type is assignable from the specified implementation , + /// and caches the result across the application using a . + /// + /// The type of the contract. + /// The implementation. + public static bool IsTypeAssignableFrom(Type implementation) + { + return IsTypeAssignableFrom(typeof(TContract), implementation); + } + + /// + /// A cached method to determine whether represents a value type. + /// + /// The implementation. + public static bool IsValueType(Type implementation) + { + return ValueTypeCache.GetOrAdd(implementation, x => x.IsValueType || x.IsPrimitive); + } + + /// + /// A cached method to determine whether is an implied value type (, or a string). + /// + /// The implementation. + public static bool IsImplicitValueType(Type implementation) + { + return ImplicitValueTypeCache.GetOrAdd(implementation, x => IsValueType(implementation) || implementation.IsEnum || implementation == typeof(string)); + } + + public static bool IsTypeAssignableFrom(object implementation) + { + if (implementation == null) throw new ArgumentNullException("implementation"); + return IsTypeAssignableFrom(implementation.GetType()); + } + + /// + /// Gets (and caches) discoverable in the current for a given . + /// + /// The source. + /// + public static FieldInfo[] CachedDiscoverableFields(Type type) + { + return GetFieldsCache.GetOrAdd( + type, + x => type + .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) + .Where(y => !y.IsInitOnly) + .ToArray()); + } + + /// + /// Gets (and caches) discoverable in the current for a given . + /// + /// The source. + /// true if the properties discovered are readable + /// true if the properties discovered are writable + /// true if the properties discovered are indexable + /// + public static PropertyInfo[] CachedDiscoverableProperties(Type type, bool mustRead = true, bool mustWrite = true, bool includeIndexed = false) + { + return GetPropertiesCache.GetOrAdd( + new Tuple(type, mustRead, mustWrite, includeIndexed), + x => type + .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) + .Where(y => (!mustRead || y.CanRead) + && (!mustWrite || y.CanWrite) + && (includeIndexed || !y.GetIndexParameters().Any())) + .ToArray()); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 6848561963..d4aea239e8 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -49,8 +49,10 @@ + + diff --git a/src/Umbraco.Tests/TypeFinderBenchmarkTests.cs b/src/Umbraco.Tests/TypeFinderBenchmarkTests.cs index f25f061361..b38bed6417 100644 --- a/src/Umbraco.Tests/TypeFinderBenchmarkTests.cs +++ b/src/Umbraco.Tests/TypeFinderBenchmarkTests.cs @@ -2,6 +2,7 @@ using System; using System.Diagnostics; using System.IO; using System.Linq; +using System.Reflection; using NUnit.Framework; using SqlCE4Umbraco; using Umbraco.Core; @@ -27,9 +28,36 @@ namespace Umbraco.Tests [Ignore("This is a benchark test")] public class TypeFinderBenchmarkTests { + /// + /// List of assemblies to scan + /// + private Assembly[] _assemblies; + [SetUp] public void Initialize() { + _assemblies = new[] + { + //both contain the type + this.GetType().Assembly, + //these dont contain the type + typeof(ApplicationStartupHandler).Assembly, + typeof(SqlCEHelper).Assembly, + typeof(CMSNode).Assembly, + typeof(System.Guid).Assembly, + typeof(NUnit.Framework.Assert).Assembly, + typeof(Microsoft.CSharp.CSharpCodeProvider).Assembly, + typeof(System.Xml.NameTable).Assembly, + typeof(System.Configuration.GenericEnumConverter).Assembly, + typeof(System.Web.SiteMap).Assembly, + typeof(TabPage).Assembly, + typeof(System.Web.Mvc.ActionResult).Assembly, + typeof(TypeFinder2).Assembly, + typeof(ISqlHelper).Assembly, + typeof(DLRScriptingEngine).Assembly, + typeof(ICultureDictionary).Assembly + }; + //we need to copy the umbracoSettings file to the output folder! File.Copy( Path.Combine(TestHelper.CurrentAssemblyDirectory, "..\\..\\..\\Umbraco.Web.UI\\config\\umbracoSettings.Release.config"), @@ -56,129 +84,75 @@ namespace Umbraco.Tests } + [Test] public void Benchmark_Old_TypeFinder_vs_New_TypeFinder_FindClassesWithAttribute() { var timer = new Stopwatch(); - var assemblies = new[] - { - //both contain the type - this.GetType().Assembly, - //these dont contain the type - typeof(ApplicationStartupHandler).Assembly, - typeof(SqlCEHelper).Assembly, - typeof(CMSNode).Assembly, - typeof(System.Guid).Assembly, - typeof(NUnit.Framework.Assert).Assembly, - typeof(Microsoft.CSharp.CSharpCodeProvider).Assembly, - typeof(System.Xml.NameTable).Assembly, - typeof(System.Configuration.GenericEnumConverter).Assembly, - typeof(System.Web.SiteMap).Assembly, - typeof(TabPage).Assembly, - typeof(System.Web.Mvc.ActionResult).Assembly, - typeof(TypeFinder2).Assembly, - typeof(ISqlHelper).Assembly, - typeof(DLRScriptingEngine).Assembly, - typeof(ICultureDictionary).Assembly - }; var finder2 = new Umbraco.Core.TypeFinder2(); timer.Start(); - var found1 = finder2.FindClassesWithAttribute(assemblies); + var found1 = finder2.FindClassesWithAttribute(_assemblies); timer.Stop(); - Console.WriteLine("Total time to find class with XsltExtensionAttribute (" + found1.Count() + ") in " + assemblies.Count() + " assemblies using new TypeFinder: " + timer.ElapsedMilliseconds); + Console.WriteLine("Total time to find class with XsltExtensionAttribute (" + found1.Count() + ") in " + _assemblies.Count() + " assemblies using new TypeFinder: " + timer.ElapsedMilliseconds); timer.Start(); - var found2 = umbraco.BusinessLogic.Utils.TypeFinder.FindClassesMarkedWithAttribute(typeof(XsltExtensionAttribute), assemblies); + var found2 = umbraco.BusinessLogic.Utils.TypeFinder.FindClassesMarkedWithAttribute(typeof(XsltExtensionAttribute), _assemblies); timer.Stop(); - Console.WriteLine("Total time to find class with XsltExtensionAttribute (" + found2.Count() + ") in " + assemblies.Count() + " assemblies using old TypeFinder: " + timer.ElapsedMilliseconds); + Console.WriteLine("Total time to find class with XsltExtensionAttribute (" + found2.Count() + ") in " + _assemblies.Count() + " assemblies using old TypeFinder: " + timer.ElapsedMilliseconds); + + Assert.AreEqual(found1.Count(), found2.Count()); } [Test] public void Benchmark_Old_TypeFinder_vs_New_TypeFinder_FindClassesOfType() { - var timer = new Stopwatch(); - var assemblies = new[] - { - //both contain the type - this.GetType().Assembly, - //these dont contain the type - typeof(ApplicationStartupHandler).Assembly, - typeof(SqlCEHelper).Assembly, - typeof(CMSNode).Assembly, - typeof(System.Guid).Assembly, - typeof(NUnit.Framework.Assert).Assembly, - typeof(Microsoft.CSharp.CSharpCodeProvider).Assembly, - typeof(System.Xml.NameTable).Assembly, - typeof(System.Configuration.GenericEnumConverter).Assembly, - typeof(System.Web.SiteMap).Assembly, - typeof(TabPage).Assembly, - typeof(System.Web.Mvc.ActionResult).Assembly, - typeof(TypeFinder2).Assembly, - typeof(ISqlHelper).Assembly, - typeof(DLRScriptingEngine).Assembly, - typeof(ICultureDictionary).Assembly - }; + var timer = new Stopwatch(); var finder2 = new Umbraco.Core.TypeFinder2(); timer.Start(); - var found1 = finder2.FindClassesOfType(assemblies); + var found1 = finder2.FindClassesOfType(_assemblies); timer.Stop(); - Console.WriteLine("Total time to find TestEditor (" + found1.Count() + ") in " + assemblies.Count() + " assemblies using new TypeFinder: " + timer.ElapsedMilliseconds); + Console.WriteLine("Total time to find TestEditor (" + found1.Count() + ") in " + _assemblies.Count() + " assemblies using new TypeFinder: " + timer.ElapsedMilliseconds); timer.Start(); - var found2 = umbraco.BusinessLogic.Utils.TypeFinder.FindClassesOfType(true, true, assemblies); + var found2 = umbraco.BusinessLogic.Utils.TypeFinder.FindClassesOfType(true, true, _assemblies); timer.Stop(); - Console.WriteLine("Total time to find TestEditor (" + found2.Count() + ") in " + assemblies.Count() + " assemblies using old TypeFinder: " + timer.ElapsedMilliseconds); + Console.WriteLine("Total time to find TestEditor (" + found2.Count() + ") in " + _assemblies.Count() + " assemblies using old TypeFinder: " + timer.ElapsedMilliseconds); + + Assert.AreEqual(found1.Count(), found2.Count()); } - + /// + /// To indicate why we had the AssemblyContainsPluginsAttribute attribute in v5, now just need to get the .hash and assembly + /// cache files created instead since this is clearly a TON faster. + /// [Test] public void Benchmark_Finding_First_Type_In_Assemblies() { - var timer = new Stopwatch(); - var assemblies = new[] - { - //both contain the type - this.GetType().Assembly, - //these dont contain the type - typeof(ApplicationStartupHandler).Assembly, - typeof(SqlCEHelper).Assembly, - typeof(CMSNode).Assembly, - typeof(System.Guid).Assembly, - typeof(NUnit.Framework.Assert).Assembly, - typeof(Microsoft.CSharp.CSharpCodeProvider).Assembly, - typeof(System.Xml.NameTable).Assembly, - typeof(System.Configuration.GenericEnumConverter).Assembly, - typeof(System.Web.SiteMap).Assembly, - typeof(TabPage).Assembly, - typeof(System.Web.Mvc.ActionResult).Assembly, - typeof(TypeFinder2).Assembly, - typeof(ISqlHelper).Assembly, - typeof(DLRScriptingEngine).Assembly, - typeof(ICultureDictionary).Assembly - }; + var timer = new Stopwatch(); var finder = new Umbraco.Core.TypeFinder2(); timer.Start(); - var found1 = finder.FindClassesOfType(assemblies); + var found1 = finder.FindClassesOfType(_assemblies); timer.Stop(); - Console.WriteLine("Total time to find TestEditor (" + found1.Count() + ") in " + assemblies.Count() + " assemblies using AssemblyContainsPluginsAttribute: " + timer.ElapsedMilliseconds); + Console.WriteLine("Total time to find TestEditor (" + found1.Count() + ") in " + _assemblies.Count() + " assemblies using AssemblyContainsPluginsAttribute: " + timer.ElapsedMilliseconds); timer.Start(); - var found2 = finder.FindClassesOfType(assemblies); + var found2 = finder.FindClassesOfType(_assemblies); timer.Stop(); - Console.WriteLine("Total time to find TestEditor (" + found2.Count() + ") in " + assemblies.Count() + " assemblies without AssemblyContainsPluginsAttribute: " + timer.ElapsedMilliseconds); + Console.WriteLine("Total time to find TestEditor (" + found2.Count() + ") in " + _assemblies.Count() + " assemblies without AssemblyContainsPluginsAttribute: " + timer.ElapsedMilliseconds); + Assert.AreEqual(found1.Count(), found2.Count()); } diff --git a/src/Umbraco.Web/umbraco.presentation/macro.cs b/src/Umbraco.Web/umbraco.presentation/macro.cs index f3c6116e42..fbc82bc396 100644 --- a/src/Umbraco.Web/umbraco.presentation/macro.cs +++ b/src/Umbraco.Web/umbraco.presentation/macro.cs @@ -840,7 +840,8 @@ namespace umbraco //also get types marked with XsltExtension attribute // zb-00042 #29949 : do not hide errors, refactor - foreach (Type xsltType in TypeFinder.FindClassesMarkedWithAttribute(typeof(XsltExtensionAttribute))) + var typeFinder = new Umbraco.Core.TypeFinder2(); + foreach (var xsltType in typeFinder.FindClassesWithAttribute()) { object[] tpAttributes = xsltType.GetCustomAttributes(typeof(XsltExtensionAttribute), true); foreach (XsltExtensionAttribute tpAttribute in tpAttributes) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/BrowseRepository.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/BrowseRepository.aspx.cs index d11dc73fd4..49c3375a66 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/BrowseRepository.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/BrowseRepository.aspx.cs @@ -41,7 +41,7 @@ namespace umbraco.presentation.developer.packages { if (!string.IsNullOrEmpty(category)) category = "&category=" + category; - iframeGen.Text = string.Format("", url, repoGuid, category, Request.ServerVariables["SERVER_NAME"], Request.ServerVariables["SERVER_PORT"], IOHelper.ResolveUrl( SystemDirectories.Umbraco ), IOHelper.ResolveUrl(SystemDirectories.Umbraco).Trim('/'), repoGuid, GlobalSettings.VersionMajor, GlobalSettings.VersionMinor, GlobalSettings.VersionPatch, UmbracoSettings.UseLegacyXmlSchema.ToString(), Environment.Version, BusinessLogic.Utils.TypeFinder.GetCurrentTrustLevel() ); + iframeGen.Text = string.Format("", url, repoGuid, category, Request.ServerVariables["SERVER_NAME"], Request.ServerVariables["SERVER_PORT"], IOHelper.ResolveUrl( SystemDirectories.Umbraco ), IOHelper.ResolveUrl(SystemDirectories.Umbraco).Trim('/'), repoGuid, GlobalSettings.VersionMajor, GlobalSettings.VersionMinor, GlobalSettings.VersionPatch, UmbracoSettings.UseLegacyXmlSchema.ToString(), Environment.Version, Umbraco.Core.SystemUtilities.GetCurrentTrustLevel() ); } #region Web Form Designer generated code diff --git a/src/Umbraco.Web/umbraco.presentation/umbracobase/restExtension.cs b/src/Umbraco.Web/umbraco.presentation/umbracobase/restExtension.cs index 300e206015..e687cdbe7c 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbracobase/restExtension.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbracobase/restExtension.cs @@ -95,13 +95,13 @@ namespace umbraco.presentation.umbracobase { //check for RestExtensionAttribute - foreach (Type t in TypeFinder.FindClassesMarkedWithAttribute(typeof(RestExtension))) + var typeFinder = new Umbraco.Core.TypeFinder2(); + foreach (var t in typeFinder.FindClassesWithAttribute()) { var temp = t.GetCustomAttributes(typeof(RestExtension), false).OfType(); - if (temp.Where(x => x.GetAlias() == extensionAlias) - .Any()) + if (temp.Any(x => x.GetAlias() == extensionAlias)) { MethodInfo mi = t.GetMethod(methodName); diff --git a/src/umbraco.businesslogic/Utils/TypeFinder.cs b/src/umbraco.businesslogic/Utils/TypeFinder.cs index f894e7f1c5..0a348a9ae6 100644 --- a/src/umbraco.businesslogic/Utils/TypeFinder.cs +++ b/src/umbraco.businesslogic/Utils/TypeFinder.cs @@ -218,6 +218,7 @@ namespace umbraco.BusinessLogic.Utils return t => (type.IsAssignableFrom(t) && (onlyConcreteClasses ? (t.IsClass && !t.IsAbstract) : true)); } + [Obsolete("This method is no longer used and will be removed")] public static IEnumerable GetFilesByExtensions(this DirectoryInfo dir, bool searchSubdirs, params string[] extensions) { var allowedExtensions = new HashSet(extensions, StringComparer.OrdinalIgnoreCase); @@ -232,30 +233,10 @@ namespace umbraco.BusinessLogic.Utils return returnedFiles; } + [Obsolete("Use Umbraco.Core.SystemUtilities.GetCurrentTrustLevel() instead")] public static AspNetHostingPermissionLevel GetCurrentTrustLevel() { - foreach (AspNetHostingPermissionLevel trustLevel in - new AspNetHostingPermissionLevel[] { - AspNetHostingPermissionLevel.Unrestricted, - AspNetHostingPermissionLevel.High, - AspNetHostingPermissionLevel.Medium, - AspNetHostingPermissionLevel.Low, - AspNetHostingPermissionLevel.Minimal - }) - { - try - { - new AspNetHostingPermission(trustLevel).Demand(); - } - catch (System.Security.SecurityException) - { - continue; - } - - return trustLevel; - } - - return AspNetHostingPermissionLevel.None; + return Umbraco.Core.SystemUtilities.GetCurrentTrustLevel(); } } } diff --git a/src/umbraco.businesslogic/Utils/TypeResolver.cs b/src/umbraco.businesslogic/Utils/TypeResolver.cs index 691bc5b2de..8dfca2426a 100644 --- a/src/umbraco.businesslogic/Utils/TypeResolver.cs +++ b/src/umbraco.businesslogic/Utils/TypeResolver.cs @@ -45,7 +45,7 @@ namespace umbraco.BusinessLogic.Utils AppDomain sandbox = AppDomain.CurrentDomain; - if (TypeFinder.GetCurrentTrustLevel() == AspNetHostingPermissionLevel.Unrestricted + if (Umbraco.Core.SystemUtilities.GetCurrentTrustLevel() == AspNetHostingPermissionLevel.Unrestricted ) { AppDomainSetup domainSetup = new AppDomainSetup(); @@ -79,7 +79,7 @@ namespace umbraco.BusinessLogic.Utils } finally { - if (TypeFinder.GetCurrentTrustLevel() == AspNetHostingPermissionLevel.Unrestricted) + if (Umbraco.Core.SystemUtilities.GetCurrentTrustLevel() == AspNetHostingPermissionLevel.Unrestricted) { AppDomain.Unload(sandbox); }