Added new TypeFinder methods for resolving types with attributes. Updated the PluginResolver to resolve IApplication
This commit is contained in:
@@ -73,14 +73,9 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
return instances;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generic method to find the specified type and cache the result
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<Type> ResolveTypes<T>()
|
||||
private IEnumerable<Type> ResolveTypes<T>(Func<IEnumerable<Type>> finder)
|
||||
{
|
||||
using (var readLock = new UpgradeableReadLock(_lock))
|
||||
{
|
||||
@@ -93,7 +88,7 @@ namespace Umbraco.Core
|
||||
|
||||
typeList = new TypeList<T>();
|
||||
|
||||
foreach (var t in TypeFinder.FindClassesOfType<T>())
|
||||
foreach (var t in finder())
|
||||
{
|
||||
typeList.AddType(t);
|
||||
}
|
||||
@@ -103,8 +98,28 @@ namespace Umbraco.Core
|
||||
}
|
||||
return typeList.GetTypes();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generic method to find the specified type and cache the result
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<Type> ResolveTypes<T>()
|
||||
{
|
||||
return ResolveTypes<T>(() => TypeFinder.FindClassesOfType<T>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generic method to find the specified type that has an attribute and cache the result
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<Type> ResolveTypesWithAttribute<T, TAttribute>()
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return ResolveTypes<T>(() => TypeFinder.FindClassesOfTypeWithAttribute<T, TAttribute>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -16,6 +16,9 @@ using System.Web.Hosting;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
|
||||
//TODO: Get the App_Code stuff in here from the old one
|
||||
|
||||
/// <summary>
|
||||
/// A utility class to find all classes of a certain type by reflection in the current bin folder
|
||||
/// of the web application.
|
||||
@@ -252,6 +255,32 @@ namespace Umbraco.Core
|
||||
return FindClassesOfType<T, TAssemblyAttribute>(new[] { assembly });
|
||||
}
|
||||
|
||||
public IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>()
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<T, TAttribute>(GetAssembliesWithKnownExclusions(), true);
|
||||
}
|
||||
|
||||
public IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return FindClassesOfTypeWithAttribute<T, TAttribute>(assemblies, true);
|
||||
}
|
||||
|
||||
public IEnumerable<Type> FindClassesOfTypeWithAttribute<T, TAttribute>(IEnumerable<Assembly> assemblies, bool onlyConcreteClasses)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
if (assemblies == null) throw new ArgumentNullException("assemblies");
|
||||
|
||||
return (from a in assemblies
|
||||
from t in GetTypesWithFormattedException(a)
|
||||
where !t.IsInterface
|
||||
&& typeof(T).IsAssignableFrom(t)
|
||||
&& t.GetCustomAttributes<TAttribute>(false).Any()
|
||||
&& (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
|
||||
select t).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches all filtered local assemblies specified for classes of the type passed in.
|
||||
/// </summary>
|
||||
@@ -262,32 +291,6 @@ namespace Umbraco.Core
|
||||
return FindClassesOfType<T>(GetAssembliesWithKnownExclusions(), true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches all assemblies specified for classes of the type passed in.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblyFiles"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<Type> FindClassesOfType<T>(IEnumerable<string> assemblyFiles)
|
||||
{
|
||||
return FindClassesOfType<T>(assemblyFiles, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches all assemblies specified for classes of the type passed in.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="assemblyFiles"></param>
|
||||
/// <param name="onlyConcreteClasses">Only resolve concrete classes that can be instantiated</param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<Type> FindClassesOfType<T>(IEnumerable<string> assemblyFiles, bool onlyConcreteClasses)
|
||||
{
|
||||
if (assemblyFiles == null) throw new ArgumentNullException("assemblyFiles");
|
||||
|
||||
var typeAndAssembly = GetAssignablesFromType<T>(assemblyFiles, onlyConcreteClasses);
|
||||
return GetTypesFromResult(typeAndAssembly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all types found of in the assemblies specified of type T
|
||||
/// </summary>
|
||||
@@ -354,40 +357,6 @@ namespace Umbraco.Core
|
||||
return FindClassesWithAttribute<T>(GetAssembliesWithKnownExclusions());
|
||||
}
|
||||
|
||||
#region Internal Methods - For testing
|
||||
/// <summary>
|
||||
/// Used to find all types in all assemblies in the specified folder
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="folder"></param>
|
||||
/// <param name="onlyConcreteClasses"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This has potential cost alot in performance so it is marked internal and should ONLY be used
|
||||
/// where absolutely necessary (i.e. Tests)
|
||||
/// </remarks>
|
||||
internal IEnumerable<Type> FindClassesOfType<T>(DirectoryInfo folder, bool onlyConcreteClasses)
|
||||
{
|
||||
var types = new List<Type>();
|
||||
types.AddRange(FindClassesOfType<T>(folder.GetFiles("*.dll").Select(x => x.FullName)));
|
||||
return types;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to find all types in all assemblies in the specified folder
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="folder"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This has potential cost alot in performance so it is marked internal and should ONLY be used
|
||||
/// where absolutely necessary (i.e. Tests)
|
||||
/// </remarks>
|
||||
internal IEnumerable<Type> FindClassesOfType<T>(DirectoryInfo folder)
|
||||
{
|
||||
return FindClassesOfType<T>(folder, true);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Internal Attributed Assembly class
|
||||
|
||||
|
||||
@@ -16,16 +16,15 @@ using umbraco.businesslogic;
|
||||
using umbraco.cms.businesslogic;
|
||||
using umbraco.uicontrols;
|
||||
|
||||
[assembly: TypeFinderBenchmarkTests.AssemblyContainsPluginsAttribute]
|
||||
[assembly: TypeFinderTests.AssemblyContainsPluginsAttribute]
|
||||
|
||||
namespace Umbraco.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Full Trust benchmark tests for typefinder and the old typefinder
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
[Ignore("This is a benchark test")]
|
||||
public class TypeFinderBenchmarkTests
|
||||
[TestFixture]
|
||||
public class TypeFinderTests
|
||||
{
|
||||
/// <summary>
|
||||
/// List of assemblies to scan
|
||||
@@ -73,18 +72,43 @@ namespace Umbraco.Tests
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
||||
public class MyTestAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public abstract class TestEditor
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[MyTestAttribute]
|
||||
public class BenchmarkTestEditor : TestEditor
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[MyTestAttribute]
|
||||
public class MyOtherTestEditor : TestEditor
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_Type_With_Attribute()
|
||||
{
|
||||
|
||||
var finder2 = new Umbraco.Core.TypeFinder2();
|
||||
|
||||
var typesFound = finder2.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();
|
||||
@@ -107,6 +131,7 @@ namespace Umbraco.Tests
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("This is a benchark test")]
|
||||
public void Benchmark_Old_TypeFinder_vs_New_TypeFinder_FindClassesOfType()
|
||||
{
|
||||
var timer = new Stopwatch();
|
||||
@@ -133,6 +158,7 @@ namespace Umbraco.Tests
|
||||
/// 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();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core;
|
||||
using umbraco.BusinessLogic.Utils;
|
||||
using umbraco.DataLayer;
|
||||
using umbraco.businesslogic;
|
||||
@@ -29,10 +30,9 @@ namespace umbraco.BusinessLogic
|
||||
public ApplicationRegistrar()
|
||||
{
|
||||
// Load all Applications by attribute and add them to the XML config
|
||||
var typeFinder = new Umbraco.Core.TypeFinder2();
|
||||
var types = typeFinder.FindClassesOfType<IApplication>()
|
||||
.Where(x => x.GetCustomAttributes(typeof(ApplicationAttribute), false).Any());
|
||||
var types = PluginTypeResolver.Current.ResolveApplications();
|
||||
|
||||
//we can have multiple attributes so we'll query for them
|
||||
var attrs = types.Select(x => (ApplicationAttribute)x.GetCustomAttributes(typeof(ApplicationAttribute), false).Single())
|
||||
.Where(x => Application.getByAlias(x.Alias) == null);
|
||||
|
||||
|
||||
@@ -20,5 +20,15 @@ namespace umbraco.businesslogic
|
||||
return resolver.ResolveTypes<IApplicationStartupHandler>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all available IApplication object
|
||||
/// </summary>
|
||||
/// <param name="resolver"></param>
|
||||
/// <returns></returns>
|
||||
internal static IEnumerable<Type> ResolveApplications(this PluginTypeResolver resolver)
|
||||
{
|
||||
return resolver.ResolveTypesWithAttribute<IApplication, ApplicationAttribute>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user