PluginManager TLC

This commit is contained in:
Stephan
2017-03-05 10:20:11 +01:00
parent becc07c2bd
commit 3b3eda5bfc
8 changed files with 636 additions and 729 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,32 +1,24 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Security;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Compilation;
using System.Web.Hosting;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
namespace Umbraco.Core
{
/// <summary>
/// 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 TypeFinder
{
private static volatile HashSet<Assembly> _localFilteredAssemblyCache = null;
private static volatile HashSet<Assembly> _localFilteredAssemblyCache;
private static readonly object LocalFilteredAssemblyCacheLocker = new object();
/// <summary>
@@ -63,7 +55,7 @@ namespace Umbraco.Core
}
catch (InvalidOperationException e)
{
if (!(e.InnerException is SecurityException))
if ((e.InnerException is SecurityException) == false)
throw;
}
@@ -99,7 +91,7 @@ namespace Umbraco.Core
}
//if for some reason they are still no assemblies, then use the AppDomain to load in already loaded assemblies.
if (!assemblies.Any())
if (assemblies.Any() == false)
{
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
{
@@ -111,12 +103,12 @@ namespace Umbraco.Core
var fileExtensions = new[] { ".cs", ".vb" }; //only vb and cs files are supported
var appCodeFolder = new DirectoryInfo(IOHelper.MapPath(IOHelper.ResolveUrl("~/App_code")));
//check if the folder exists and if there are any files in it with the supported file extensions
if (appCodeFolder.Exists && (fileExtensions.Any(x => appCodeFolder.GetFiles("*" + x).Any())))
if (appCodeFolder.Exists && fileExtensions.Any(x => appCodeFolder.GetFiles("*" + x).Any()))
{
try
{
var appCodeAssembly = Assembly.Load("App_Code");
if (!assemblies.Contains(appCodeAssembly)) // BuildManager will find App_Code already
if (assemblies.Contains(appCodeAssembly) == false) // BuildManager will find App_Code already
assemblies.Add(appCodeAssembly);
}
catch (FileNotFoundException ex)
@@ -128,7 +120,7 @@ namespace Umbraco.Core
}
catch (InvalidOperationException e)
{
if (!(e.InnerException is SecurityException))
if (e.InnerException is SecurityException == false)
throw;
}
@@ -145,23 +137,16 @@ namespace Umbraco.Core
internal static HashSet<Assembly> GetAssembliesWithKnownExclusions(
IEnumerable<Assembly> excludeFromResults = null)
{
if (_localFilteredAssemblyCache == null)
lock (LocalFilteredAssemblyCacheLocker)
{
lock (LocalFilteredAssemblyCacheLocker)
{
//double check
if (_localFilteredAssemblyCache == null)
{
_localFilteredAssemblyCache = new HashSet<Assembly>();
var assemblies = GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter);
foreach (var a in assemblies)
{
_localFilteredAssemblyCache.Add(a);
}
}
}
// double check
if (_localFilteredAssemblyCache != null)
return _localFilteredAssemblyCache;
var assemblies = GetFilteredAssemblies(excludeFromResults, KnownAssemblyExclusionFilter);
_localFilteredAssemblyCache = new HashSet<Assembly>(assemblies);
return _localFilteredAssemblyCache;
}
return _localFilteredAssemblyCache;
}
/// <summary>
@@ -180,9 +165,9 @@ namespace Umbraco.Core
exclusionFilter = new string[] { };
return GetAllAssemblies()
.Where(x => !excludeFromResults.Contains(x)
&& !x.GlobalAssemblyCache
&& !exclusionFilter.Any(f => x.FullName.StartsWith(f)));
.Where(x => excludeFromResults.Contains(x) == false
&& x.GlobalAssemblyCache == false
&& exclusionFilter.Any(f => x.FullName.StartsWith(f)) == false);
}
/// <summary>
@@ -298,7 +283,7 @@ namespace Umbraco.Core
{
if (assemblies == null) throw new ArgumentNullException("assemblies");
return GetClasses(assignTypeFrom, assemblies, onlyConcreteClasses,
return GetClassesWithBaseType(assignTypeFrom, assemblies, onlyConcreteClasses,
//the additional filter will ensure that any found types also have the attribute applied.
t => t.GetCustomAttributes<TAttribute>(false).Any());
}
@@ -324,7 +309,7 @@ namespace Umbraco.Core
{
if (assemblies == null) throw new ArgumentNullException("assemblies");
return GetClasses(typeof(T), assemblies, onlyConcreteClasses);
return GetClassesWithBaseType(typeof(T), assemblies, onlyConcreteClasses);
}
/// <summary>
@@ -363,105 +348,9 @@ namespace Umbraco.Core
IEnumerable<Assembly> assemblies,
bool onlyConcreteClasses)
{
if (assemblies == null) throw new ArgumentNullException("assemblies");
if (TypeHelper.IsTypeAssignableFrom<Attribute>(attributeType) == false)
throw new ArgumentException("The type specified: " + attributeType + " is not an Attribute type");
var foundAttributedTypes = new HashSet<Type>();
var assemblyList = assemblies.ToArray();
//find all assembly references that are referencing the attribute type's assembly since we
//should only be scanning those assemblies because any other assembly will definitely not
//contain a class that has this attribute.
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(attributeType, assemblyList);
//get a list of non-referenced assemblies (we'll use this when we recurse below)
var otherAssemblies = assemblyList.Where(x => referencedAssemblies.Contains(x) == false).ToArray();
//loop through the referenced assemblies
foreach (var a in referencedAssemblies)
{
//get all types in this assembly
var allTypes = GetTypesWithFormattedException(a)
.ToArray();
var attributedTypes = new Type[] { };
try
{
//now filter the types based on the onlyConcreteClasses flag, not interfaces, not static classes but have
//the specified attribute
attributedTypes = allTypes
.Where(t => (TypeHelper.IsNonStaticClass(t)
&& (onlyConcreteClasses == false || t.IsAbstract == false))
//the type must have this attribute
&& t.GetCustomAttributes(attributeType, false).Any())
.ToArray();
}
catch (TypeLoadException ex)
{
LogHelper.Error(typeof(TypeFinder), string.Format("Could not query types on {0} assembly, this is most likely due to this assembly not being compatible with the current Umbraco version", a), ex);
continue;
}
//add the types to our list to return
foreach (var t in attributedTypes)
{
foundAttributedTypes.Add(t);
}
//get all attributes of the type being searched for
var allAttributeTypes = allTypes.Where(attributeType.IsAssignableFrom);
//now we need to include types that may be inheriting from sub classes of the attribute type being searched for
//so we will search in assemblies that reference those types too.
foreach (var subTypesInAssembly in allAttributeTypes.GroupBy(x => x.Assembly))
{
//So that we are not scanning too much, we need to group the sub types:
// * if there is more than 1 sub type in the same assembly then we should only search on the 'lowest base' type.
// * We should also not search for sub types if the type is sealed since you cannot inherit from a sealed class
// * We should not search for sub types if the type is static since you cannot inherit from them.
var subTypeList = subTypesInAssembly
.Where(t => t.IsSealed == false && TypeHelper.IsStaticClass(t) == false)
.ToArray();
var baseClassAttempt = TypeHelper.GetLowestBaseType(subTypeList);
//if there's a base class amongst the types then we'll only search for that type.
//otherwise we'll have to search for all of them.
var subTypesToSearch = new HashSet<Type>();
if (baseClassAttempt.Success)
{
subTypesToSearch.Add(baseClassAttempt.Result);
}
else
{
foreach (var t in subTypeList)
{
subTypesToSearch.Add(t);
}
}
foreach (var typeToSearch in subTypesToSearch)
{
//recursively find the types inheriting from this sub type in the other non-scanned assemblies.
var foundTypes = FindClassesWithAttribute(typeToSearch, otherAssemblies, onlyConcreteClasses);
foreach (var f in foundTypes)
{
foundAttributedTypes.Add(f);
}
}
}
}
return foundAttributedTypes;
return GetClassesWithAttribute(attributeType, assemblies, onlyConcreteClasses);
}
/// <summary>
/// Finds the classes with attribute.
/// </summary>
@@ -485,122 +374,129 @@ namespace Umbraco.Core
return FindClassesWithAttribute<T>(GetAssembliesWithKnownExclusions());
}
#region Private methods
private static IEnumerable<Type> GetClassesWithAttribute(
Type attributeType,
IEnumerable<Assembly> assemblies,
bool onlyConcreteClasses)
{
if (typeof(Attribute).IsAssignableFrom(attributeType) == false)
throw new ArgumentException("Type " + attributeType + " is not an Attribute type.");
var candidateAssemblies = new HashSet<Assembly>(assemblies);
var attributeAssemblyIsCandidate = candidateAssemblies.Contains(attributeType.Assembly);
candidateAssemblies.Remove(attributeType.Assembly);
var types = new List<Type>();
var stack = new Stack<Assembly>();
stack.Push(attributeType.Assembly);
while (stack.Count > 0)
{
var assembly = stack.Pop();
Type[] assemblyTypes = null;
if (assembly != attributeType.Assembly || attributeAssemblyIsCandidate)
{
// get all assembly types that can be assigned to baseType
try
{
assemblyTypes = GetTypesWithFormattedException(assembly)
.ToArray(); // in try block
}
catch (TypeLoadException ex)
{
LogHelper.Error(typeof(TypeFinder), string.Format("Could not query types on {0} assembly, this is most likely due to this assembly not being compatible with the current Umbraco version", assembly), ex);
continue;
}
types.AddRange(assemblyTypes.Where(x =>
x.IsClass // only classes
&& (x.IsAbstract == false || x.IsSealed == false) // ie non-static, static is abstract and sealed
&& x.IsNestedPrivate == false // exclude nested private
&& (onlyConcreteClasses == false || x.IsAbstract == false) // exclude abstract
&& x.GetCustomAttribute<HideFromTypeFinderAttribute>() == null // exclude hidden
&& x.GetCustomAttributes(attributeType, false).Any())); // marked with the attribute
}
if (assembly != attributeType.Assembly && assemblyTypes.Where(attributeType.IsAssignableFrom).Any() == false)
continue;
foreach (var referencing in TypeHelper.GetReferencingAssemblies(assembly, candidateAssemblies))
{
candidateAssemblies.Remove(referencing);
stack.Push(referencing);
}
}
return types;
}
/// <summary>
/// Finds types that are assignable from the assignTypeFrom parameter and will scan for these types in the assembly
/// list passed in, however we will only scan assemblies that have a reference to the assignTypeFrom Type or any type
/// deriving from the base type.
/// </summary>
/// <param name="assignTypeFrom"></param>
/// <param name="baseType"></param>
/// <param name="assemblies"></param>
/// <param name="onlyConcreteClasses"></param>
/// <param name="additionalFilter">An additional filter to apply for what types will actually be included in the return value</param>
/// <returns></returns>
private static IEnumerable<Type> GetClasses(
Type assignTypeFrom,
private static IEnumerable<Type> GetClassesWithBaseType(
Type baseType,
IEnumerable<Assembly> assemblies,
bool onlyConcreteClasses,
Func<Type, bool> additionalFilter = null)
{
//the default filter will always return true.
if (additionalFilter == null)
var candidateAssemblies = new HashSet<Assembly>(assemblies);
var baseTypeAssemblyIsCandidate = candidateAssemblies.Contains(baseType.Assembly);
candidateAssemblies.Remove(baseType.Assembly);
var types = new List<Type>();
var stack = new Stack<Assembly>();
stack.Push(baseType.Assembly);
while (stack.Count > 0)
{
additionalFilter = type => true;
}
var assembly = stack.Pop();
var foundAssignableTypes = new HashSet<Type>();
var assemblyList = assemblies.ToArray();
//find all assembly references that are referencing the current type's assembly since we
//should only be scanning those assemblies because any other assembly will definitely not
//contain sub type's of the one we're currently looking for
var referencedAssemblies = TypeHelper.GetReferencedAssemblies(assignTypeFrom, assemblyList);
//get a list of non-referenced assemblies (we'll use this when we recurse below)
var otherAssemblies = assemblyList.Where(x => referencedAssemblies.Contains(x) == false).ToArray();
//loop through the referenced assemblies
foreach (var a in referencedAssemblies)
{
//get all types in the assembly that are sub types of the current type
var allSubTypes = GetTypesWithFormattedException(a)
.Where(assignTypeFrom.IsAssignableFrom)
.ToArray();
var filteredTypes = new Type[] { };
try
// get all assembly types that can be assigned to baseType
Type[] assemblyTypes = null;
if (assembly != baseType.Assembly || baseTypeAssemblyIsCandidate)
{
//now filter the types based on the onlyConcreteClasses flag, not interfaces, not static classes
filteredTypes = allSubTypes
.Where(t => (TypeHelper.IsNonStaticClass(t)
//Do not include nested private classes - since we are in full trust now this will find those too!
&& t.IsNestedPrivate == false
&& (onlyConcreteClasses == false || t.IsAbstract == false)
//Do not include classes that are flagged to hide from the type finder
&& t.GetCustomAttribute<HideFromTypeFinderAttribute>() == null
&& additionalFilter(t)))
.ToArray();
try
{
assemblyTypes = GetTypesWithFormattedException(assembly)
.Where(baseType.IsAssignableFrom)
.ToArray(); // in try block
}
catch (TypeLoadException ex)
{
LogHelper.Error(typeof(TypeFinder), string.Format("Could not query types on {0} assembly, this is most likely due to this assembly not being compatible with the current Umbraco version", assembly), ex);
continue;
}
types.AddRange(assemblyTypes.Where(x =>
x.IsClass // only classes
&& (x.IsAbstract == false || x.IsSealed == false) // ie non-static, static is abstract and sealed
&& x.IsNestedPrivate == false // exclude nested private
&& (onlyConcreteClasses == false || x.IsAbstract == false) // exclude abstract
&& x.GetCustomAttribute<HideFromTypeFinderAttribute>() == null // exclude hidden
&& (additionalFilter == null || additionalFilter(x)))); // filter
}
catch (TypeLoadException ex)
{
LogHelper.Error(typeof(TypeFinder), string.Format("Could not query types on {0} assembly, this is most likely due to this assembly not being compatible with the current Umbraco version", a), ex);
if (assembly != baseType.Assembly && assemblyTypes.All(x => x.IsSealed))
continue;
}
//add the types to our list to return
foreach (var t in filteredTypes)
foreach (var referencing in TypeHelper.GetReferencingAssemblies(assembly, candidateAssemblies))
{
foundAssignableTypes.Add(t);
candidateAssemblies.Remove(referencing);
stack.Push(referencing);
}
//now we need to include types that may be inheriting from sub classes of the type being searched for
//so we will search in assemblies that reference those types too.
foreach (var subTypesInAssembly in allSubTypes.GroupBy(x => x.Assembly))
{
//So that we are not scanning too much, we need to group the sub types:
// * if there is more than 1 sub type in the same assembly then we should only search on the 'lowest base' type.
// * We should also not search for sub types if the type is sealed since you cannot inherit from a sealed class
// * We should not search for sub types if the type is static since you cannot inherit from them.
var subTypeList = subTypesInAssembly
.Where(t => t.IsSealed == false && TypeHelper.IsStaticClass(t) == false)
.ToArray();
var baseClassAttempt = TypeHelper.GetLowestBaseType(subTypeList);
//if there's a base class amongst the types then we'll only search for that type.
//otherwise we'll have to search for all of them.
var subTypesToSearch = new HashSet<Type>();
if (baseClassAttempt.Success)
{
subTypesToSearch.Add(baseClassAttempt.Result);
}
else
{
foreach (var t in subTypeList)
{
subTypesToSearch.Add(t);
}
}
foreach (var typeToSearch in subTypesToSearch)
{
//recursively find the types inheriting from this sub type in the other non-scanned assemblies.
var foundTypes = GetClasses(typeToSearch, otherAssemblies, onlyConcreteClasses, additionalFilter);
foreach (var f in foundTypes)
{
foundAssignableTypes.Add(f);
}
}
}
}
return foundAssignableTypes;
return types;
}
internal static IEnumerable<Type> GetTypesWithFormattedException(Assembly a)
@@ -666,7 +562,6 @@ namespace Umbraco.Core
#endregion
public static Type GetTypeByName(string typeName)
{
var type = BuildManager.GetType(typeName, false);
@@ -684,6 +579,5 @@ namespace Umbraco.Core
.Select(x => x.GetType(typeName))
.FirstOrDefault(x => x != null);
}
}
}

View File

@@ -30,44 +30,43 @@ namespace Umbraco.Core
/// <summary>
/// Find all assembly references that are referencing the assignTypeFrom Type's assembly found in the assemblyList
/// </summary>
/// <param name="assignTypeFrom"></param>
/// <param name="assemblies"></param>
/// <param name="assembly">The referenced assembly.</param>
/// <param name="assemblies">A list of assemblies.</param>
/// <returns></returns>
/// <remarks>
/// If the assembly of the assignTypeFrom Type is in the App_Code assembly, then we return nothing since things cannot
/// reference that assembly, same with the global.asax assembly.
/// </remarks>
public static Assembly[] GetReferencedAssemblies(Type assignTypeFrom, IEnumerable<Assembly> assemblies)
public static Assembly[] GetReferencingAssemblies(Assembly assembly, IEnumerable<Assembly> assemblies)
{
//check if it is the app_code assembly.
//check if it is App_global.asax assembly
if (assignTypeFrom.Assembly.IsAppCodeAssembly() || assignTypeFrom.Assembly.IsGlobalAsaxAssembly())
// check if it is the app_code assembly.
// check if it is App_global.asax assembly
if (assembly.IsAppCodeAssembly() || assembly.IsGlobalAsaxAssembly())
{
return Enumerable.Empty<Assembly>().ToArray();
}
//find all assembly references that are referencing the current type's assembly since we
//should only be scanning those assemblies because any other assembly will definitely not
//contain sub type's of the one we're currently looking for
return assemblies
.Where(assembly =>
assembly == assignTypeFrom.Assembly
|| HasReferenceToAssemblyWithName(assembly, assignTypeFrom.Assembly.GetName().Name))
.ToArray();
// find all assembly references that are referencing the current type's assembly since we
// should only be scanning those assemblies because any other assembly will definitely not
// contain sub type's of the one we're currently looking for
var name = assembly.GetName().Name;
return assemblies.Where(x => x == assembly || HasReference(x, name)).ToArray();
}
/// <summary>
/// checks if the assembly has a reference with the same name as the expected assembly name.
/// </summary>
/// <param name="assembly"></param>
/// <param name="expectedAssemblyName"></param>
/// <param name="name"></param>
/// <returns></returns>
private static bool HasReferenceToAssemblyWithName(Assembly assembly, string expectedAssemblyName)
{
return assembly
.GetReferencedAssemblies()
.Select(a => a.Name)
.Contains(expectedAssemblyName, StringComparer.Ordinal);
public static bool HasReference(Assembly assembly, string name)
{
// ReSharper disable once LoopCanBeConvertedToQuery - no!
foreach (var a in assembly.GetReferencedAssemblies())
{
if (string.Equals(a.Name, name, StringComparison.OrdinalIgnoreCase)) return true;
}
return false;
}
/// <summary>

View File

@@ -35,7 +35,7 @@ namespace Umbraco.Tests.CodeFirst
}
};
}
[Test]
@@ -84,10 +84,7 @@ namespace Umbraco.Tests.CodeFirst
var foundTypes = _pluginManager.ResolveContentTypeBaseTypes();
Assert.That(foundTypes.Count(), Is.EqualTo(15));
Assert.AreEqual(1,
_pluginManager.GetTypeLists()
.Count(x => x.IsList<ContentTypeBase>(PluginManager.TypeResolutionKind.FindAllTypes)));
Assert.AreEqual(1, _pluginManager.TypeLists.Count(x => x.BaseType == typeof (ContentTypeBase) && x.AttributeType == null));
}
}
}

View File

@@ -35,14 +35,14 @@ namespace Umbraco.Tests.Plugins
public void Initialize()
{
//this ensures its reset
_manager = new PluginManager(new ActivatorServiceProvider(), new NullCacheProvider(),
_manager = new PluginManager(new ActivatorServiceProvider(), new NullCacheProvider(),
new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
//for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
//TODO: Should probably update this so it only searches this assembly and add custom types to be found
_manager.AssembliesToScan = new[]
{
this.GetType().Assembly,
this.GetType().Assembly,
typeof(ApplicationStartupHandler).Assembly,
typeof(SqlCEHelper).Assembly,
typeof(CMSNode).Assembly,
@@ -161,7 +161,7 @@ namespace Umbraco.Tests.Plugins
public void Detect_Legacy_Plugin_File_List()
{
var tempFolder = IOHelper.MapPath("~/App_Data/TEMP/PluginCache");
var filePath= Path.Combine(tempFolder, string.Format("umbraco-plugins.{0}.list", NetworkHelper.FileSafeMachineName));
File.WriteAllText(filePath, @"<?xml version=""1.0"" encoding=""utf-8""?>
@@ -170,12 +170,11 @@ namespace Umbraco.Tests.Plugins
<add type=""umbraco.macroCacheRefresh, umbraco, Version=6.0.0.0, Culture=neutral, PublicKeyToken=null"" />
</baseType>
</plugins>");
Assert.IsTrue(_manager.DetectLegacyPluginListFile());
Assert.IsEmpty(_manager.ReadCache()); // uber-legacy cannot be read
File.Delete(filePath);
//now create a valid one
File.WriteAllText(filePath, @"<?xml version=""1.0"" encoding=""utf-8""?>
<plugins>
<baseType type=""umbraco.interfaces.ICacheRefresher"" resolutionType=""FindAllTypes"">
@@ -183,19 +182,32 @@ namespace Umbraco.Tests.Plugins
</baseType>
</plugins>");
Assert.IsFalse(_manager.DetectLegacyPluginListFile());
Assert.IsEmpty(_manager.ReadCache()); // legacy cannot be read
File.Delete(filePath);
File.WriteAllText(filePath, @"IContentFinder
MyContentFinder
AnotherContentFinder
");
Assert.IsNotNull(_manager.ReadCache()); // works
}
[Test]
public void Create_Cached_Plugin_File()
{
var types = new[] { typeof(PluginManager), typeof(PluginManagerTests), typeof(UmbracoContext) };
var types = new[] { typeof (PluginManager), typeof (PluginManagerTests), typeof (UmbracoContext) };
//yes this is silly, none of these types inherit from string, but this is just to test the xml file format
_manager.UpdateCachedPluginsFile<string>(types, PluginManager.TypeResolutionKind.FindAllTypes);
var typeList1 = new PluginManager.TypeList(typeof (object), null);
foreach (var type in types) typeList1.Add(type);
_manager.AddTypeList(typeList1);
_manager.WriteCache();
var plugins = _manager.TryGetCachedPluginsFromFile<string>(PluginManager.TypeResolutionKind.FindAllTypes);
var diffType = _manager.TryGetCachedPluginsFromFile<string>(PluginManager.TypeResolutionKind.FindAttributedTypes);
var plugins = _manager.TryGetCached(typeof (object), null);
var diffType = _manager.TryGetCached(typeof (object), typeof (ObsoleteAttribute));
Assert.IsTrue(plugins.Success);
//this will be false since there is no cache of that type resolution kind
@@ -211,7 +223,7 @@ namespace Umbraco.Tests.Plugins
public void PluginHash_From_String()
{
var s = "hello my name is someone".GetHashCode().ToString("x", CultureInfo.InvariantCulture);
var output = PluginManager.ConvertPluginsHashFromHex(s);
var output = PluginManager.ConvertHashToInt64(s);
Assert.AreNotEqual(0, output);
}
@@ -241,7 +253,7 @@ namespace Umbraco.Tests.Plugins
var list1 = new[] { f1, f2, f3, f4, f5, f6 };
var list2 = new[] { f1, f3, f5 };
var list3 = new[] { f1, f3, f5, f7 };
//Act
var hash1 = PluginManager.GetFileHash(list1, new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
var hash2 = PluginManager.GetFileHash(list2, new ProfilingLogger(Mock.Of<ILogger>(), Mock.Of<IProfiler>()));
@@ -260,9 +272,7 @@ namespace Umbraco.Tests.Plugins
{
var foundTypes1 = _manager.ResolveFindMeTypes();
var foundTypes2 = _manager.ResolveFindMeTypes();
Assert.AreEqual(1,
_manager.GetTypeLists()
.Count(x => x.IsList<IFindMe>(PluginManager.TypeResolutionKind.FindAllTypes)));
Assert.AreEqual(1, _manager.TypeLists.Count(x => x.BaseType == typeof(IFindMe) && x.AttributeType == null));
}
[Test]
@@ -345,20 +355,20 @@ namespace Umbraco.Tests.Plugins
{
var types = new HashSet<PluginManager.TypeList>();
var propEditors = new PluginManager.TypeList<PropertyEditor>(PluginManager.TypeResolutionKind.FindAllTypes);
var propEditors = new PluginManager.TypeList(typeof (PropertyEditor), null);
propEditors.Add(typeof(LabelPropertyEditor));
types.Add(propEditors);
var found = types.SingleOrDefault(x => x.IsList<PropertyEditor>(PluginManager.TypeResolutionKind.FindAllTypes));
var found = types.SingleOrDefault(x => x.BaseType == typeof (PropertyEditor) && x.AttributeType == null);
Assert.IsNotNull(found);
//This should not find a type list of this type
var shouldNotFind = types.SingleOrDefault(x => x.IsList<IParameterEditor>(PluginManager.TypeResolutionKind.FindAllTypes));
var shouldNotFind = types.SingleOrDefault(x => x.BaseType == typeof (IParameterEditor) && x.AttributeType == null);
Assert.IsNull(shouldNotFind);
}
[XsltExtension("Blah.Blah")]
public class MyXsltExtension
{

View File

@@ -26,11 +26,11 @@ using Umbraco.Web.BaseRest;
namespace Umbraco.Tests.Plugins
{
/// <summary>
/// Tests for typefinder
/// </summary>
[TestFixture]
[TestFixture]
public class TypeFinderTests
{
/// <summary>
@@ -43,7 +43,7 @@ namespace Umbraco.Tests.Plugins
{
_assemblies = new[]
{
this.GetType().Assembly,
this.GetType().Assembly,
typeof(ApplicationStartupHandler).Assembly,
typeof(SqlCEHelper).Assembly,
typeof(CMSNode).Assembly,
@@ -75,7 +75,7 @@ namespace Umbraco.Tests.Plugins
[Test]
public void Find_Classes_Of_Type()
{
var typesFound = TypeFinder.FindClassesOfType<IApplicationStartupHandler>(_assemblies);
var typesFound = TypeFinder.FindClassesOfType<IApplicationStartupHandler>(_assemblies);
var originalTypesFound = TypeFinderOriginal.FindClassesOfType<IApplicationStartupHandler>(_assemblies);
Assert.AreEqual(originalTypesFound.Count(), typesFound.Count());
@@ -118,7 +118,7 @@ namespace Umbraco.Tests.Plugins
}
}
}
}
[Ignore]
@@ -149,7 +149,7 @@ namespace Umbraco.Tests.Plugins
}
}
}
}
public class MyTag : ITag
@@ -161,7 +161,7 @@ namespace Umbraco.Tests.Plugins
public class MySuperTag : MyTag
{
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
@@ -203,7 +203,7 @@ namespace Umbraco.Tests.Plugins
/// This is a modified version of: http://www.dominicpettifer.co.uk/Blog/44/how-to-get-a-reference-to-all-assemblies-in-the--bin-folder
/// </summary>
/// <remarks>
/// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been
/// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been
/// loaded in the CLR, not all assemblies.
/// See these threads:
/// http://issues.umbraco.org/issue/U5-198
@@ -329,8 +329,8 @@ namespace Umbraco.Tests.Plugins
}
catch (SecurityException)
{
//we will just ignore this because this will fail
//in medium trust for system assemblies, we get an exception but we just want to continue until we get to
//we will just ignore this because this will fail
//in medium trust for system assemblies, we get an exception but we just want to continue until we get to
//an assembly that is ok.
}
}
@@ -347,9 +347,9 @@ namespace Umbraco.Tests.Plugins
}
catch (SecurityException)
{
//we will just ignore this because if we are trying to do a call to:
//we will just ignore this because if we are trying to do a call to:
// AssemblyName.ReferenceMatchesDefinition(a.GetName(), assemblyName)))
//in medium trust for system assemblies, we get an exception but we just want to continue until we get to
//in medium trust for system assemblies, we get an exception but we just want to continue until we get to
//an assembly that is ok.
}
}
@@ -361,7 +361,7 @@ namespace Umbraco.Tests.Plugins
}
/// <summary>
/// Return a list of found local Assemblies excluding the known assemblies we don't want to scan
/// 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.
/// </summary>
@@ -429,7 +429,7 @@ namespace Umbraco.Tests.Plugins
"RouteDebugger,",
"SqlCE4Umbraco,",
"umbraco.datalayer,",
"umbraco.interfaces,",
"umbraco.interfaces,",
"umbraco.providers,",
"Umbraco.Web.UI,",
"umbraco.webservices",
@@ -631,5 +631,5 @@ namespace Umbraco.Tests.Plugins
}
}
}

View File

@@ -60,7 +60,7 @@ namespace Umbraco.Tests.TestHelpers
public override void TearDown()
{
base.TearDown();
// reset settings
SettingsForTests.Reset();
UmbracoContext.Current = null;
@@ -117,7 +117,7 @@ namespace Umbraco.Tests.TestHelpers
}
/// <summary>
/// By default this returns false which means the plugin manager will not be reset so it doesn't need to re-scan
/// By default this returns false which means the plugin manager will not be reset so it doesn't need to re-scan
/// all of the assemblies. Inheritors can override this if plugin manager resetting is required, generally needs
/// to be set to true if the SetupPluginManager has been overridden.
/// </summary>

View File

@@ -18,7 +18,7 @@ namespace umbraco.businesslogic
internal static IEnumerable<Type> ResolveApplications(this PluginManager resolver)
{
//don't cache the result of this because it is only used once during app startup, caching will just add a bit more mem overhead for no reason
return resolver.ResolveTypesWithAttribute<IApplication, ApplicationAttribute>(cacheResult:false);
return resolver.ResolveTypesWithAttribute<IApplication, ApplicationAttribute>(cache:false);
}
/// <summary>
@@ -29,7 +29,7 @@ namespace umbraco.businesslogic
internal static IEnumerable<Type> ResolveAttributedTrees(this PluginManager resolver)
{
//don't cache the result of this because it is only used once during app startup, caching will just add a bit more mem overhead for no reason
return resolver.ResolveTypesWithAttribute<ITree, TreeAttribute>(cacheResult:false);
return resolver.ResolveTypesWithAttribute<ITree, TreeAttribute>(cache:false);
}
}