Updated ApplicationTreeRegistrar to use PluginTypeResolver, created unit tests for resolving trees/applications

This commit is contained in:
shannon@ShandemVaio
2012-07-27 10:37:12 +06:00
parent 58fbe9f4ab
commit 09a68f9376
6 changed files with 85 additions and 14 deletions

View File

@@ -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<TypeList> _types = new HashSet<TypeList>();
private IEnumerable<Assembly> _assemblies;
/// <summary>
/// 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.
/// </summary>
internal IEnumerable<Assembly> AssembliesToScan
{
get { return _assemblies ?? (_assemblies = TypeFinder2.GetAssembliesWithKnownExclusions()); }
set { _assemblies = value; }
}
/// <summary>
/// Used to create instances of the specified type based on the resolved/cached plugin types
@@ -107,7 +119,7 @@ namespace Umbraco.Core
/// <returns></returns>
internal IEnumerable<Type> ResolveTypes<T>()
{
return ResolveTypes<T>(() => TypeFinder.FindClassesOfType<T>());
return ResolveTypes<T>(() => TypeFinder.FindClassesOfType<T>(AssembliesToScan));
}
/// <summary>
@@ -119,7 +131,7 @@ namespace Umbraco.Core
internal IEnumerable<Type> ResolveTypesWithAttribute<T, TAttribute>()
where TAttribute : Attribute
{
return ResolveTypes<T>(() => TypeFinder.FindClassesOfTypeWithAttribute<T, TAttribute>());
return ResolveTypes<T>(() => TypeFinder.FindClassesOfTypeWithAttribute<T, TAttribute>(AssembliesToScan));
}
/// <summary>

View File

@@ -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
{

View File

@@ -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,

View File

@@ -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<ApplicationAttribute>(false).Single())
.Where(x => Application.getByAlias(x.Alias) == null);
var allAliases = Application.getAll().Select(x => x.alias).Concat(attrs.Select(x => x.Alias));

View File

@@ -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<ITree>()
.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<Type, TreeAttribute>(x,
(TreeAttribute)x.GetCustomAttributes(typeof(TreeAttribute), false).Single()))
.Where(x => ApplicationTree.getByAlias(x.Item2.Alias) == null);
var items = types
.Select(x =>
new Tuple<Type, TreeAttribute>(x, x.GetCustomAttributes<TreeAttribute>(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) + "'";

View File

@@ -21,7 +21,7 @@ namespace umbraco.businesslogic
}
/// <summary>
/// Returns all available IApplication object
/// Returns all available IApplication in application
/// </summary>
/// <param name="resolver"></param>
/// <returns></returns>
@@ -30,5 +30,15 @@ namespace umbraco.businesslogic
return resolver.ResolveTypesWithAttribute<IApplication, ApplicationAttribute>();
}
/// <summary>
/// Returns all available ITrees in application
/// </summary>
/// <param name="resolver"></param>
/// <returns></returns>
internal static IEnumerable<Type> ResolveTrees(this PluginTypeResolver resolver)
{
return resolver.ResolveTypesWithAttribute<ITree, TreeAttribute>();
}
}
}