diff --git a/src/Umbraco.Core/PluginTypeResolver.cs b/src/Umbraco.Core/PluginTypeResolver.cs index d2e373fdd5..be16fc6ff3 100644 --- a/src/Umbraco.Core/PluginTypeResolver.cs +++ b/src/Umbraco.Core/PluginTypeResolver.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading; @@ -49,6 +50,17 @@ namespace Umbraco.Core internal readonly TypeFinder2 TypeFinder = new TypeFinder2(); private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); private readonly HashSet _types = new HashSet(); + private IEnumerable _assemblies; + + /// + /// Gets/sets which assemblies to scan when type finding, generally used for unit testing, if not explicitly set + /// this will search all assemblies known to have plugins and exclude ones known to not have them. + /// + internal IEnumerable AssembliesToScan + { + get { return _assemblies ?? (_assemblies = TypeFinder2.GetAssembliesWithKnownExclusions()); } + set { _assemblies = value; } + } /// /// Used to create instances of the specified type based on the resolved/cached plugin types @@ -107,7 +119,7 @@ namespace Umbraco.Core /// internal IEnumerable ResolveTypes() { - return ResolveTypes(() => TypeFinder.FindClassesOfType()); + return ResolveTypes(() => TypeFinder.FindClassesOfType(AssembliesToScan)); } /// @@ -119,7 +131,7 @@ namespace Umbraco.Core internal IEnumerable ResolveTypesWithAttribute() where TAttribute : Attribute { - return ResolveTypes(() => TypeFinder.FindClassesOfTypeWithAttribute()); + return ResolveTypes(() => TypeFinder.FindClassesOfTypeWithAttribute(AssembliesToScan)); } /// diff --git a/src/Umbraco.Tests/PluginTypeResolverTests.cs b/src/Umbraco.Tests/PluginTypeResolverTests.cs index b9538191b7..b5428e42e7 100644 --- a/src/Umbraco.Tests/PluginTypeResolverTests.cs +++ b/src/Umbraco.Tests/PluginTypeResolverTests.cs @@ -1,12 +1,47 @@ using System.Linq; using NUnit.Framework; +using SqlCE4Umbraco; using Umbraco.Core; +using Umbraco.Web; +using umbraco.DataLayer; +using umbraco.MacroEngines; +using umbraco.MacroEngines.Iron; +using umbraco.businesslogic; +using umbraco.cms.businesslogic; +using umbraco.uicontrols; namespace Umbraco.Tests { public class PluginTypeResolverTests { + [SetUp] + public void Initialize() + { + //for testing, we'll specify which assemblies are scanned for the PluginTypeResolver + PluginTypeResolver.Current.AssembliesToScan = new[] + { + this.GetType().Assembly, + 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, + typeof(UmbracoContext).Assembly + + }; + } + [Test] public void Ensure_Only_One_Type_List_Created() { @@ -22,6 +57,20 @@ namespace Umbraco.Tests Assert.AreEqual(2, foundTypes1.Count()); } + [Test] + public void Resolves_Trees() + { + var trees = PluginTypeResolver.Current.ResolveTrees(); + Assert.AreEqual(26, trees.Count()); + } + + [Test] + public void Resolves_Applications() + { + var apps = PluginTypeResolver.Current.ResolveApplications(); + Assert.AreEqual(7, apps.Count()); + } + public interface IFindMe { diff --git a/src/Umbraco.Tests/TypeFinderBenchmarkTests.cs b/src/Umbraco.Tests/TypeFinderBenchmarkTests.cs index 97954bcb85..2c61502a78 100644 --- a/src/Umbraco.Tests/TypeFinderBenchmarkTests.cs +++ b/src/Umbraco.Tests/TypeFinderBenchmarkTests.cs @@ -36,9 +36,7 @@ namespace Umbraco.Tests { _assemblies = new[] { - //both contain the type this.GetType().Assembly, - //these dont contain the type typeof(ApplicationStartupHandler).Assembly, typeof(SqlCEHelper).Assembly, typeof(CMSNode).Assembly, diff --git a/src/umbraco.businesslogic/ApplicationRegistrar.cs b/src/umbraco.businesslogic/ApplicationRegistrar.cs index 47139638f3..29cd59ba37 100644 --- a/src/umbraco.businesslogic/ApplicationRegistrar.cs +++ b/src/umbraco.businesslogic/ApplicationRegistrar.cs @@ -32,8 +32,10 @@ namespace umbraco.BusinessLogic // Load all Applications by attribute and add them to the XML config 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()) + //since applications don't populate their metadata from the attribute and because it is an interface, + //we need to interrogate the attributes for the data. Would be better to have a base class that contains + //metadata populated by the attribute. Oh well i guess. + var attrs = types.Select(x => x.GetCustomAttributes(false).Single()) .Where(x => Application.getByAlias(x.Alias) == null); var allAliases = Application.getAll().Select(x => x.alias).Concat(attrs.Select(x => x.Alias)); diff --git a/src/umbraco.businesslogic/ApplicationTreeRegistrar.cs b/src/umbraco.businesslogic/ApplicationTreeRegistrar.cs index 2a9cd706d0..5ba139a3ff 100644 --- a/src/umbraco.businesslogic/ApplicationTreeRegistrar.cs +++ b/src/umbraco.businesslogic/ApplicationTreeRegistrar.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Xml.Linq; +using Umbraco.Core; using umbraco.BusinessLogic.Utils; using umbraco.DataLayer; using umbraco.businesslogic; @@ -29,14 +30,13 @@ namespace umbraco.BusinessLogic public ApplicationTreeRegistrar() { - // Load all Applications by attribute and add them to the XML config - var typeFinder = new Umbraco.Core.TypeFinder2(); - var types = typeFinder.FindClassesOfType() - .Where(x => x.GetCustomAttributes(typeof(TreeAttribute), false).Any()); + // Load all Trees by attribute and add them to the XML config + var types = PluginTypeResolver.Current.ResolveTrees(); - var items = types.Select(x => new Tuple(x, - (TreeAttribute)x.GetCustomAttributes(typeof(TreeAttribute), false).Single())) - .Where(x => ApplicationTree.getByAlias(x.Item2.Alias) == null); + var items = types + .Select(x => + new Tuple(x, x.GetCustomAttributes(false).Single())) + .Where(x => ApplicationTree.getByAlias(x.Item2.Alias) == null); var allAliases = ApplicationTree.getAll().Select(x => x.Alias).Concat(items.Select(x => x.Item2.Alias)); var inString = "'" + string.Join("','", allAliases) + "'"; diff --git a/src/umbraco.businesslogic/PluginTypeResolverExtensions.cs b/src/umbraco.businesslogic/PluginTypeResolverExtensions.cs index f3acbfd55e..724ad770ba 100644 --- a/src/umbraco.businesslogic/PluginTypeResolverExtensions.cs +++ b/src/umbraco.businesslogic/PluginTypeResolverExtensions.cs @@ -21,7 +21,7 @@ namespace umbraco.businesslogic } /// - /// Returns all available IApplication object + /// Returns all available IApplication in application /// /// /// @@ -30,5 +30,15 @@ namespace umbraco.businesslogic return resolver.ResolveTypesWithAttribute(); } + /// + /// Returns all available ITrees in application + /// + /// + /// + internal static IEnumerable ResolveTrees(this PluginTypeResolver resolver) + { + return resolver.ResolveTypesWithAttribute(); + } + } } \ No newline at end of file