Renamed TypeFinder2 to Umbraco.Core.TypeFinder. Obsoleted old TypeFinder and cleaned up non-used methods
in the new TypeFinder. Updated some unit tests and removed benchmark tests since we already have the benchmarks.
This commit is contained in:
@@ -109,7 +109,7 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
internal IEnumerable<Assembly> AssembliesToScan
|
||||
{
|
||||
get { return _assemblies ?? (_assemblies = TypeFinder2.GetAssembliesWithKnownExclusions()); }
|
||||
get { return _assemblies ?? (_assemblies = TypeFinder.GetAssembliesWithKnownExclusions()); }
|
||||
set { _assemblies = value; }
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<Type> ResolveTypes<T>()
|
||||
{
|
||||
return ResolveTypes<T>(() => TypeFinder2.FindClassesOfType<T>(AssembliesToScan));
|
||||
return ResolveTypes<T>(() => TypeFinder.FindClassesOfType<T>(AssembliesToScan));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -224,7 +224,7 @@ namespace Umbraco.Core
|
||||
internal IEnumerable<Type> ResolveTypesWithAttribute<T, TAttribute>()
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return ResolveTypes<T>(() => TypeFinder2.FindClassesOfTypeWithAttribute<T, TAttribute>(AssembliesToScan));
|
||||
return ResolveTypes<T>(() => TypeFinder.FindClassesOfTypeWithAttribute<T, TAttribute>(AssembliesToScan));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -236,7 +236,7 @@ namespace Umbraco.Core
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return ResolveTypes<TAttribute>(
|
||||
() => TypeFinder2.FindClassesWithAttribute<TAttribute>(AssembliesToScan),
|
||||
() => TypeFinder.FindClassesWithAttribute<TAttribute>(AssembliesToScan),
|
||||
true);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,15 +23,11 @@ namespace Umbraco.Core
|
||||
/// A utility class to find all classes of a certain type by reflection in the current bin folder
|
||||
/// of the web application.
|
||||
/// </summary>
|
||||
public static class TypeFinder2
|
||||
public static class TypeFinder
|
||||
{
|
||||
|
||||
private static readonly ConcurrentBag<Assembly> LocalFilteredAssemblyCache = new ConcurrentBag<Assembly>();
|
||||
private static readonly ReaderWriterLockSlim LocalFilteredAssemblyCacheLocker = new ReaderWriterLockSlim();
|
||||
/// <summary>
|
||||
/// Caches attributed assembly information so they don't have to be re-read
|
||||
/// </summary>
|
||||
private static readonly AttributedAssemblyList AttributedAssemblies = new AttributedAssemblyList();
|
||||
private static ReadOnlyCollection<Assembly> _allAssemblies = null;
|
||||
private static ReadOnlyCollection<Assembly> _binFolderAssemblies = null;
|
||||
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
|
||||
@@ -188,69 +184,6 @@ namespace Umbraco.Core
|
||||
"Examine."
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns assemblies found in the specified path that the the specified custom attribute type applied to them
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblies">The assemblies to search on</param>
|
||||
/// <returns></returns>
|
||||
internal static IEnumerable<Assembly> FindAssembliesWithAttribute<T>(IEnumerable<Assembly> assemblies)
|
||||
where T : Attribute
|
||||
{
|
||||
|
||||
var foundAssemblies = (from a in assemblies
|
||||
//if its already registered, then ignore
|
||||
where !AttributedAssemblies.IsRegistered<T>(a)
|
||||
let customAttributes = a.GetCustomAttributes(typeof(T), false)
|
||||
where customAttributes.Any()
|
||||
select a).ToList();
|
||||
//now update the cache
|
||||
foreach (var a in foundAssemblies)
|
||||
{
|
||||
AttributedAssemblies.Add(new AttributedAssembly { Assembly = a, PluginAttributeType = typeof(T), AssemblyFolder = null });
|
||||
}
|
||||
|
||||
//We must do a ToList() here because it is required to be serializable when using other app domains.
|
||||
return AttributedAssemblies
|
||||
.Where(x => x.PluginAttributeType == typeof(T)
|
||||
&& assemblies.Select(y => y.FullName).Contains(x.Assembly.FullName))
|
||||
.Select(x => x.Assembly)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns found types in assemblies attributed with the specifed attribute type
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAssemblyAttribute"></typeparam>
|
||||
/// <param name="assemblies">The assemblies to search on</param>
|
||||
/// <returns></returns>
|
||||
internal static IEnumerable<Type> FindClassesOfType<T, TAssemblyAttribute>(IEnumerable<Assembly> assemblies)
|
||||
where TAssemblyAttribute : Attribute
|
||||
{
|
||||
var found = FindAssembliesWithAttribute<TAssemblyAttribute>(assemblies);
|
||||
return GetAssignablesFromType<T>(found, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns found types in an assembly attributed with the specifed attribute type
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAssemblyAttribute">The type of the assembly attribute.</typeparam>
|
||||
/// <param name="assembly">The assembly.</param>
|
||||
/// <returns></returns>
|
||||
/// <remarks></remarks>
|
||||
internal static IEnumerable<Type> FindClassesOfType<T, TAssemblyAttribute>(Assembly assembly)
|
||||
where TAssemblyAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfType<T, TAssemblyAttribute>(new[] { assembly });
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>()
|
||||
where TAttribute : Attribute
|
||||
@@ -328,14 +261,28 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute<T>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
where T : Attribute
|
||||
{
|
||||
return FindClassesWithAttribute(typeof(T), assemblies, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the classes with attribute.
|
||||
/// </summary>
|
||||
/// <param name="type">The attribute type </param>
|
||||
/// <param name="assemblies">The assemblies.</param>
|
||||
/// <param name="onlyConcreteClasses">if set to <c>true</c> only concrete classes.</param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Type> FindClassesWithAttribute(Type type, IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
if (!TypeHelper.IsTypeAssignableFrom<Attribute>(type))
|
||||
throw new ArgumentException("The type specified: " + type + " is not an Attribute type");
|
||||
|
||||
var l = new List<Type>();
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
var types = from t in GetTypesWithFormattedException(a)
|
||||
where !t.IsInterface && t.GetCustomAttributes<T>(false).Any() && (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
where !t.IsInterface && t.GetCustomAttributes(type, false).Any() && (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
select t;
|
||||
l.AddRange(types);
|
||||
}
|
||||
@@ -367,67 +314,8 @@ namespace Umbraco.Core
|
||||
}
|
||||
|
||||
|
||||
#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; }
|
||||
internal Assembly Assembly { get; set; }
|
||||
internal Type PluginAttributeType { get; set; }
|
||||
}
|
||||
private class AttributedAssemblyList : List<AttributedAssembly>
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines if that type has been registered with the folder
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="folder"></param>
|
||||
/// <returns></returns>
|
||||
internal bool IsRegistered<T>(DirectoryInfo folder)
|
||||
{
|
||||
return this.Any(x => x.PluginAttributeType == typeof(T)
|
||||
&& x.AssemblyFolder.FullName.ToUpper() == folder.FullName.ToUpper());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the assembly is already registered
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assembly"></param>
|
||||
/// <returns></returns>
|
||||
internal bool IsRegistered<T>(Assembly assembly)
|
||||
{
|
||||
return this.Any(x => x.PluginAttributeType == typeof(T)
|
||||
&& x.Assembly.FullName.ToUpper() == assembly.FullName.ToUpper());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
private static IEnumerable<Type> GetTypesFromResult(Dictionary<string, string> result)
|
||||
{
|
||||
return (from type in result
|
||||
let ass = Assembly.Load(type.Value)
|
||||
where ass != null
|
||||
select ass.GetType(type.Key, false)).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of assignables of type T from a collection of files
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="files">The files.</param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
private static Dictionary<string, string> GetAssignablesFromType<T>(IEnumerable<string> files, bool onlyConcreteClasses)
|
||||
{
|
||||
return GetTypes(typeof(T), files, onlyConcreteClasses);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of assignables of type T from a collection of assemblies
|
||||
/// </summary>
|
||||
@@ -471,35 +359,6 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns of a collection of type names from a collection of assembky files.
|
||||
/// </summary>
|
||||
/// <param name="assignTypeFrom">The assign type.</param>
|
||||
/// <param name="assemblyFiles">The assembly files.</param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
private static Dictionary<string, string> GetTypes(Type assignTypeFrom, IEnumerable<string> assemblyFiles, bool onlyConcreteClasses)
|
||||
{
|
||||
var result = new Dictionary<string, string>();
|
||||
foreach (var assembly in
|
||||
assemblyFiles.Where(File.Exists).Select(Assembly.LoadFile).Where(assembly => assembly != null))
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (Type t in
|
||||
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);
|
||||
}
|
||||
}
|
||||
catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
Debug.WriteLine("Error reading assembly " + assembly.FullName + ": " + ex.Message);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
<Compile Include="TypeExtensions.cs" />
|
||||
<Compile Include="ReadLock.cs" />
|
||||
<Compile Include="SystemUtilities.cs" />
|
||||
<Compile Include="TypeFinder2.cs" />
|
||||
<Compile Include="TypeFinder.cs" />
|
||||
<Compile Include="TypeHelper.cs" />
|
||||
<Compile Include="UpgradeableReadLock.cs" />
|
||||
<Compile Include="DelegateEqualityComparer.cs" />
|
||||
|
||||
@@ -19,7 +19,12 @@ namespace Umbraco.Tests
|
||||
[SetUp]
|
||||
public void Initialize()
|
||||
{
|
||||
//reset each test
|
||||
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Resolution.IsFrozen = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Umbraco.Tests
|
||||
typeof(System.Web.SiteMap).Assembly,
|
||||
typeof(TabPage).Assembly,
|
||||
typeof(System.Web.Mvc.ActionResult).Assembly,
|
||||
typeof(TypeFinder2).Assembly,
|
||||
typeof(TypeFinder).Assembly,
|
||||
typeof(ISqlHelper).Assembly,
|
||||
typeof(DLRScriptingEngine).Assembly,
|
||||
typeof(ICultureDictionary).Assembly,
|
||||
|
||||
@@ -17,8 +17,6 @@ using umbraco.businesslogic;
|
||||
using umbraco.cms.businesslogic;
|
||||
using umbraco.uicontrols;
|
||||
|
||||
[assembly: TypeFinderTests.AssemblyContainsPluginsAttribute]
|
||||
|
||||
namespace Umbraco.Tests
|
||||
{
|
||||
/// <summary>
|
||||
@@ -51,28 +49,15 @@ namespace Umbraco.Tests
|
||||
typeof(System.Web.SiteMap).Assembly,
|
||||
typeof(TabPage).Assembly,
|
||||
typeof(System.Web.Mvc.ActionResult).Assembly,
|
||||
typeof(TypeFinder2).Assembly,
|
||||
typeof(TypeFinder).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"),
|
||||
Path.Combine(TestHelper.CurrentAssemblyDirectory, "umbracoSettings.config"),
|
||||
true);
|
||||
UmbracoSettings.SettingsFilePath = TestHelper.CurrentAssemblyDirectory + "\\";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Informs the system that the assembly tagged with this attribute contains plugins and the system should scan and load them
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
|
||||
public class AssemblyContainsPluginsAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
||||
public class MyTestAttribute : Attribute
|
||||
{
|
||||
@@ -100,81 +85,12 @@ namespace Umbraco.Tests
|
||||
public void Get_Type_With_Attribute()
|
||||
{
|
||||
|
||||
var typesFound = TypeFinder2.FindClassesOfTypeWithAttribute<TestEditor, MyTestAttribute>(_assemblies);
|
||||
var typesFound = TypeFinder.FindClassesOfTypeWithAttribute<TestEditor, MyTestAttribute>(_assemblies);
|
||||
|
||||
Assert.AreEqual(2, typesFound.Count());
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("This is a benchark test")]
|
||||
public void Benchmark_Old_TypeFinder_vs_New_TypeFinder_FindClassesWithAttribute()
|
||||
{
|
||||
var timer = new Stopwatch();
|
||||
|
||||
timer.Start();
|
||||
var found1 = TypeFinder2.FindClassesWithAttribute<XsltExtensionAttribute>(_assemblies);
|
||||
timer.Stop();
|
||||
|
||||
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);
|
||||
timer.Stop();
|
||||
|
||||
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]
|
||||
[Ignore("This is a benchark test")]
|
||||
public void Benchmark_Old_TypeFinder_vs_New_TypeFinder_FindClassesOfType()
|
||||
{
|
||||
var timer = new Stopwatch();
|
||||
|
||||
|
||||
timer.Start();
|
||||
var found1 = TypeFinder2.FindClassesOfType<TestEditor>(_assemblies);
|
||||
timer.Stop();
|
||||
|
||||
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<TestEditor>(true, true, _assemblies);
|
||||
timer.Stop();
|
||||
|
||||
Console.WriteLine("Total time to find TestEditor (" + found2.Count() + ") in " + _assemblies.Count() + " assemblies using old TypeFinder: " + timer.ElapsedMilliseconds);
|
||||
|
||||
Assert.AreEqual(found1.Count(), found2.Count());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
[Test]
|
||||
[Ignore("This is a benchark test")]
|
||||
public void Benchmark_Finding_First_Type_In_Assemblies()
|
||||
{
|
||||
var timer = new Stopwatch();
|
||||
|
||||
|
||||
timer.Start();
|
||||
var found1 = TypeFinder2.FindClassesOfType<TestEditor, AssemblyContainsPluginsAttribute>(_assemblies);
|
||||
timer.Stop();
|
||||
|
||||
Console.WriteLine("Total time to find TestEditor (" + found1.Count() + ") in " + _assemblies.Count() + " assemblies using AssemblyContainsPluginsAttribute: " + timer.ElapsedMilliseconds);
|
||||
|
||||
timer.Start();
|
||||
var found2 = TypeFinder2.FindClassesOfType<TestEditor>(_assemblies);
|
||||
timer.Stop();
|
||||
|
||||
Console.WriteLine("Total time to find TestEditor (" + found2.Count() + ") in " + _assemblies.Count() + " assemblies without AssemblyContainsPluginsAttribute: " + timer.ElapsedMilliseconds);
|
||||
|
||||
Assert.AreEqual(found1.Count(), found2.Count());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -15,73 +15,20 @@ namespace umbraco.BusinessLogic.Utils
|
||||
/// A utility class to find all classes of a certain type by reflection in the current bin folder
|
||||
/// of the web application.
|
||||
/// </summary>
|
||||
[Obsolete("Use Umbraco.Core.TypeFinder instead")]
|
||||
public static class TypeFinder
|
||||
{
|
||||
// zb-00044 #29989 : refactor FindClassesMarkedWithAttribute
|
||||
|
||||
internal static IEnumerable<Type> FindClassesMarkedWithAttribute(Type attribute, IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
List<Type> types = new List<Type>();
|
||||
bool searchGAC = false;
|
||||
|
||||
foreach (Assembly assembly in assemblies)
|
||||
{
|
||||
// skip if the assembly is part of the GAC
|
||||
if (!searchGAC && assembly.GlobalAssemblyCache)
|
||||
continue;
|
||||
|
||||
types.AddRange(FindClassesMarkedWithAttribute(assembly, attribute));
|
||||
}
|
||||
|
||||
// also add types from app_code, if any
|
||||
|
||||
var fileExtension = UmbracoSettings.AppCodeFileExtensionsList.ToArray();
|
||||
var appCodeFolder = new DirectoryInfo(IOHelper.MapPath(IOHelper.ResolveUrl("~/App_code")));
|
||||
if (appCodeFolder.Exists && appCodeFolder.GetFilesByExtensions(true, fileExtension).Any())
|
||||
{
|
||||
types.AddRange(FindClassesMarkedWithAttribute(Assembly.Load("App_Code"), attribute));
|
||||
}
|
||||
|
||||
return types.Distinct();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches all loaded assemblies for classes marked with the attribute passed in.
|
||||
/// </summary>
|
||||
/// <returns>A list of found types</returns>
|
||||
[Obsolete("Use Umbraco.Core.TypeFinder.FindClassesWithAttribute instead")]
|
||||
public static IEnumerable<Type> FindClassesMarkedWithAttribute(Type attribute)
|
||||
{
|
||||
|
||||
return FindClassesMarkedWithAttribute(attribute, AppDomain.CurrentDomain.GetAssemblies());
|
||||
}
|
||||
|
||||
static IEnumerable<Type> FindClassesMarkedWithAttribute(Assembly assembly, Type attribute)
|
||||
{
|
||||
// DF: Fix Codeplex #30479 - Dynamic assemblies in Umbraco cause XSLTs to break - TypeFinder.cs
|
||||
// Just return if the assembly is dynamic.
|
||||
if (assembly.ManifestModule.GetType().Namespace == "System.Reflection.Emit") return new List<Type>();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
return assembly.GetExportedTypes().Where(type => type.GetCustomAttributes(attribute, true).Length > 0);
|
||||
}
|
||||
catch (ReflectionTypeLoadException ex)
|
||||
{
|
||||
if (GlobalSettings.DebugMode)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendFormat("Unable to load one or more of the types in assembly '{0}'. Exceptions were thrown:", assembly.FullName);
|
||||
foreach (Exception e in ex.LoaderExceptions)
|
||||
sb.AppendFormat("\n{0}: {1}", e.GetType().FullName, e.Message);
|
||||
throw new Exception(sb.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// return the types that were loaded, ignore those that could not be loaded
|
||||
return ex.Types;
|
||||
}
|
||||
}
|
||||
return Umbraco.Core.TypeFinder.FindClassesWithAttribute(
|
||||
attribute,
|
||||
Umbraco.Core.TypeFinder.GetAssembliesWithKnownExclusions(),
|
||||
true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -89,9 +36,10 @@ namespace umbraco.BusinessLogic.Utils
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of object to search for</typeparam>
|
||||
/// <returns>A list of found types</returns>
|
||||
[Obsolete("Use Umbraco.Core.TypeFinder.FindClassesOfType instead")]
|
||||
public static List<Type> FindClassesOfType<T>()
|
||||
{
|
||||
return FindClassesOfType<T>(true);
|
||||
return Umbraco.Core.TypeFinder.FindClassesOfType<T>().ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -100,13 +48,12 @@ namespace umbraco.BusinessLogic.Utils
|
||||
/// <typeparam name="T">The type of object to search for</typeparam>
|
||||
/// <param name="useSeperateAppDomain">true if a seperate app domain should be used to query the types. This is safer as it is able to clear memory after loading the types.</param>
|
||||
/// <returns>A list of found types</returns>
|
||||
[Obsolete("Use Umbraco.Core.TypeFinder.FindClassesOfType instead")]
|
||||
public static List<Type> FindClassesOfType<T>(bool useSeperateAppDomain)
|
||||
{
|
||||
return FindClassesOfType<T>(useSeperateAppDomain, true);
|
||||
return Umbraco.Core.TypeFinder.FindClassesOfType<T>().ToList();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Searches all loaded assemblies for classes of the type passed in.
|
||||
/// </summary>
|
||||
@@ -114,110 +61,12 @@ namespace umbraco.BusinessLogic.Utils
|
||||
/// <param name="useSeperateAppDomain">true if a seperate app domain should be used to query the types. This is safer as it is able to clear memory after loading the types.</param>
|
||||
/// <param name="onlyConcreteClasses">True to only return classes that can be constructed</param>
|
||||
/// <returns>A list of found types</returns>
|
||||
[Obsolete("Use Umbraco.Core.TypeFinder.FindClassesOfType instead")]
|
||||
public static List<Type> FindClassesOfType<T>(bool useSeperateAppDomain, bool onlyConcreteClasses)
|
||||
{
|
||||
return FindClassesOfType<T>(useSeperateAppDomain, onlyConcreteClasses, null);
|
||||
}
|
||||
|
||||
|
||||
static string GetAssemblyPath(Assembly ass)
|
||||
{
|
||||
var codeBase = ass.CodeBase;
|
||||
var uri = new Uri(codeBase);
|
||||
return uri.LocalPath;
|
||||
}
|
||||
|
||||
internal static List<Type> FindClassesOfType<T>(bool useSeperateAppDomain, bool onlyConcreteClasses, IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
if (useSeperateAppDomain)
|
||||
{
|
||||
string binFolder = Path.Combine(IO.IOHelper.MapPath("/", false), "bin");
|
||||
|
||||
string[] strTypes;
|
||||
if (assemblies == null)
|
||||
{
|
||||
strTypes = TypeResolver.GetAssignablesFromType<T>(binFolder, "*.dll");
|
||||
}
|
||||
else
|
||||
{
|
||||
strTypes = TypeResolver.GetAssignablesFromType<T>(assemblies.Select(GetAssemblyPath).ToArray());
|
||||
}
|
||||
|
||||
List<Type> types = new List<Type>();
|
||||
|
||||
foreach (string type in strTypes)
|
||||
types.Add(Type.GetType(type));
|
||||
|
||||
// also add types from app_code
|
||||
try
|
||||
{
|
||||
// only search the App_Code folder if it's not empty
|
||||
DirectoryInfo appCodeFolder = new DirectoryInfo(IOHelper.MapPath(IOHelper.ResolveUrl("~/App_code")));
|
||||
if (appCodeFolder.GetFiles().Length > 0)
|
||||
{
|
||||
foreach (Type type in System.Reflection.Assembly.Load("App_Code").GetExportedTypes())
|
||||
types.Add(type);
|
||||
}
|
||||
}
|
||||
catch { } // Empty catch - this just means that an App_Code assembly wasn't generated by the files in folder
|
||||
|
||||
return types.FindAll(OnlyConcreteClasses(typeof(T), onlyConcreteClasses));
|
||||
}
|
||||
else
|
||||
return FindClassesOfType(typeof(T), onlyConcreteClasses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds all classes with the specified type
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="onlyConcreteClasses"> </param>
|
||||
/// <param name="assemblies"> </param>
|
||||
/// <returns>A list of found classes</returns>
|
||||
private static List<Type> FindClassesOfType(Type type, bool onlyConcreteClasses, IEnumerable<Assembly> assemblies = null)
|
||||
{
|
||||
bool searchGAC = false;
|
||||
|
||||
List<Type> classesOfType = new List<Type>();
|
||||
|
||||
Assembly[] a;
|
||||
if (assemblies == null)
|
||||
{
|
||||
a = AppDomain.CurrentDomain.GetAssemblies();
|
||||
}
|
||||
else
|
||||
{
|
||||
a = assemblies.ToArray();
|
||||
}
|
||||
|
||||
foreach (Assembly assembly in a)
|
||||
{
|
||||
//don't check any types if the assembly is part of the GAC
|
||||
if (!searchGAC && assembly.GlobalAssemblyCache)
|
||||
continue;
|
||||
|
||||
Type[] publicTypes;
|
||||
//need try catch block as some assemblies do not support this (i.e.RefEmit_InMemoryManifestModule)
|
||||
try
|
||||
{
|
||||
publicTypes = assembly.GetExportedTypes();
|
||||
}
|
||||
catch { continue; }
|
||||
|
||||
List<Type> listOfTypes = new List<Type>();
|
||||
listOfTypes.AddRange(publicTypes);
|
||||
List<Type> foundTypes = listOfTypes.FindAll(OnlyConcreteClasses(type, onlyConcreteClasses));
|
||||
Type[] outputTypes = new Type[foundTypes.Count];
|
||||
foundTypes.CopyTo(outputTypes);
|
||||
classesOfType.AddRange(outputTypes);
|
||||
}
|
||||
|
||||
return classesOfType;
|
||||
}
|
||||
|
||||
private static Predicate<Type> OnlyConcreteClasses(Type type, bool onlyConcreteClasses)
|
||||
{
|
||||
return t => (type.IsAssignableFrom(t) && (onlyConcreteClasses ? (t.IsClass && !t.IsAbstract) : true));
|
||||
return Umbraco.Core.TypeFinder.FindClassesOfType<T>(
|
||||
Umbraco.Core.TypeFinder.GetAssembliesWithKnownExclusions(),
|
||||
onlyConcreteClasses).ToList();
|
||||
}
|
||||
|
||||
[Obsolete("This method is no longer used and will be removed")]
|
||||
@@ -240,5 +89,6 @@ namespace umbraco.BusinessLogic.Utils
|
||||
{
|
||||
return Umbraco.Core.SystemUtilities.GetCurrentTrustLevel();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ using umbraco.cms.businesslogic.workflow;
|
||||
using umbraco.interfaces;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Linq;
|
||||
using TypeFinder = Umbraco.Core.TypeFinder;
|
||||
|
||||
namespace umbraco.BusinessLogic.Actions
|
||||
{
|
||||
@@ -59,7 +60,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(
|
||||
TypeFinder2.FindClassesOfType<IAction>(PluginManager.Current.AssembliesToScan));
|
||||
TypeFinder.FindClassesOfType<IAction>(PluginManager.Current.AssembliesToScan));
|
||||
|
||||
RegisterIActionHandlers();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user