diff --git a/src/Umbraco.Core/PluginTypeResolver.cs b/src/Umbraco.Core/PluginTypeResolver.cs
index 426029de61..8440aadb02 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;
@@ -9,7 +10,7 @@ namespace Umbraco.Core
{
///
- /// Used to resolve all plugin types
+ /// Used to resolve all plugin types and cache them
///
///
///
@@ -49,17 +50,41 @@ 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 resolve and create instances of the specified type based on the resolved/cached plugin types
+ ///
+ ///
+ /// set to true if an exception is to be thrown if there is an error during instantiation
+ ///
+ internal IEnumerable FindAndCreateInstances(bool throwException = false)
+ {
+ var types = ResolveTypes();
+ return CreateInstances(types, throwException);
+ }
///
/// Used to create instances of the specified type based on the resolved/cached plugin types
///
///
+ ///
+ /// set to true if an exception is to be thrown if there is an error during instantiation
///
- internal IEnumerable CreateInstances()
+ internal IEnumerable CreateInstances(IEnumerable types, bool throwException = false)
{
- var types = ResolveTypes();
var instances = new List();
- foreach(var t in types)
+ foreach (var t in types)
{
try
{
@@ -70,17 +95,29 @@ namespace Umbraco.Core
{
//TODO: Need to fix logging so this doesn't bork if no SQL connection
//Log.Add(LogTypes.Error, -1, "Error loading ILookup: " + ex.ToString());
+ if (throwException)
+ {
+ throw ex;
+ }
}
}
return instances;
- }
+ }
///
- /// Generic method to find the specified type and cache the result
+ /// Used to create an instance of the specified type based on the resolved/cached plugin types
///
///
+ ///
+ ///
///
- internal IEnumerable ResolveTypes()
+ internal T CreateInstance(Type type, bool throwException = false)
+ {
+ var instances = CreateInstances(new[] {type}, throwException);
+ return instances.FirstOrDefault();
+ }
+
+ private IEnumerable ResolveTypes(Func> finder)
{
using (var readLock = new UpgradeableReadLock(_lock))
{
@@ -93,7 +130,7 @@ namespace Umbraco.Core
typeList = new TypeList();
- foreach (var t in TypeFinder.FindClassesOfType())
+ foreach (var t in finder())
{
typeList.AddType(t);
}
@@ -103,8 +140,28 @@ namespace Umbraco.Core
}
return typeList.GetTypes();
}
+ }
+ ///
+ /// Generic method to find the specified type and cache the result
+ ///
+ ///
+ ///
+ internal IEnumerable ResolveTypes()
+ {
+ return ResolveTypes(() => TypeFinder.FindClassesOfType(AssembliesToScan));
+ }
+ ///
+ /// Generic method to find the specified type that has an attribute and cache the result
+ ///
+ ///
+ ///
+ ///
+ internal IEnumerable ResolveTypesWithAttribute()
+ where TAttribute : Attribute
+ {
+ return ResolveTypes(() => TypeFinder.FindClassesOfTypeWithAttribute(AssembliesToScan));
}
///
@@ -116,6 +173,8 @@ namespace Umbraco.Core
return _types;
}
+
+
#region Private classes
internal abstract class TypeList
{
diff --git a/src/Umbraco.Core/Properties/AssemblyInfo.cs b/src/Umbraco.Core/Properties/AssemblyInfo.cs
index 49c9f88d05..229c77c8d8 100644
--- a/src/Umbraco.Core/Properties/AssemblyInfo.cs
+++ b/src/Umbraco.Core/Properties/AssemblyInfo.cs
@@ -21,4 +21,6 @@ using System.Runtime.InteropServices;
[assembly: InternalsVisibleTo("umbraco")]
[assembly: InternalsVisibleTo("Umbraco.Tests")]
[assembly: InternalsVisibleTo("businesslogic")]
+[assembly: InternalsVisibleTo("cms")]
+[assembly: InternalsVisibleTo("umbraco.editorControls")]
diff --git a/src/Umbraco.Core/Resolving/MultipleResolverBase.cs b/src/Umbraco.Core/Resolving/MultipleResolverBase.cs
index 77c892f93c..01e4c861f8 100644
--- a/src/Umbraco.Core/Resolving/MultipleResolverBase.cs
+++ b/src/Umbraco.Core/Resolving/MultipleResolverBase.cs
@@ -3,6 +3,9 @@ using System.Threading;
namespace Umbraco.Core.Resolving
{
+ //NOTE: This class should also support creating instances of the object and managing their lifespan,
+ // for example, some resolvers would want to return new object each time, per request or per application lifetime.
+
///
/// A Resolver which manages an ordered list of objects.
///
diff --git a/src/Umbraco.Core/TypeFinder2.cs b/src/Umbraco.Core/TypeFinder2.cs
index 8f9f67b4bc..d5641be4a5 100644
--- a/src/Umbraco.Core/TypeFinder2.cs
+++ b/src/Umbraco.Core/TypeFinder2.cs
@@ -16,6 +16,9 @@ using System.Web.Hosting;
namespace Umbraco.Core
{
+
+ //TODO: Get the App_Code stuff in here from the old one
+
///
/// 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(new[] { assembly });
}
+ public IEnumerable FindClassesOfTypeWithAttribute()
+ where TAttribute : Attribute
+ {
+ return FindClassesOfTypeWithAttribute(GetAssembliesWithKnownExclusions(), true);
+ }
+
+ public IEnumerable FindClassesOfTypeWithAttribute(IEnumerable assemblies)
+ where TAttribute : Attribute
+ {
+ return FindClassesOfTypeWithAttribute(assemblies, true);
+ }
+
+ public IEnumerable FindClassesOfTypeWithAttribute(IEnumerable 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(false).Any()
+ && (!onlyConcreteClasses || (t.IsClass && !t.IsAbstract))
+ select t).ToList();
+ }
+
///
/// Searches all filtered local assemblies specified for classes of the type passed in.
///
@@ -262,32 +291,6 @@ namespace Umbraco.Core
return FindClassesOfType(GetAssembliesWithKnownExclusions(), true);
}
- ///
- /// Searches all assemblies specified for classes of the type passed in.
- ///
- ///
- ///
- ///
- public IEnumerable FindClassesOfType(IEnumerable assemblyFiles)
- {
- return FindClassesOfType(assemblyFiles, true);
- }
-
- ///
- /// Searches all assemblies specified for classes of the type passed in.
- ///
- ///
- ///
- /// Only resolve concrete classes that can be instantiated
- ///
- public IEnumerable FindClassesOfType(IEnumerable assemblyFiles, bool onlyConcreteClasses)
- {
- if (assemblyFiles == null) throw new ArgumentNullException("assemblyFiles");
-
- var typeAndAssembly = GetAssignablesFromType(assemblyFiles, onlyConcreteClasses);
- return GetTypesFromResult(typeAndAssembly);
- }
-
///
/// Returns all types found of in the assemblies specified of type T
///
@@ -354,40 +357,6 @@ namespace Umbraco.Core
return FindClassesWithAttribute(GetAssembliesWithKnownExclusions());
}
- #region Internal Methods - For testing
- ///
- /// Used to find all types in all assemblies in the specified folder
- ///
- ///
- ///
- ///
- ///
- ///
- /// This has potential cost alot in performance so it is marked internal and should ONLY be used
- /// where absolutely necessary (i.e. Tests)
- ///
- internal IEnumerable FindClassesOfType(DirectoryInfo folder, bool onlyConcreteClasses)
- {
- var types = new List();
- types.AddRange(FindClassesOfType(folder.GetFiles("*.dll").Select(x => x.FullName)));
- return types;
- }
-
- ///
- /// Used to find all types in all assemblies in the specified folder
- ///
- ///
- ///
- ///
- ///
- /// This has potential cost alot in performance so it is marked internal and should ONLY be used
- /// where absolutely necessary (i.e. Tests)
- ///
- internal IEnumerable FindClassesOfType(DirectoryInfo folder)
- {
- return FindClassesOfType(folder, true);
- }
- #endregion
#region Internal Attributed Assembly class
diff --git a/src/Umbraco.Tests/DataTypeFactoryTests.cs b/src/Umbraco.Tests/DataTypeFactoryTests.cs
new file mode 100644
index 0000000000..d8f4a22546
--- /dev/null
+++ b/src/Umbraco.Tests/DataTypeFactoryTests.cs
@@ -0,0 +1,106 @@
+using System;
+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.cms.businesslogic.datatype;
+using umbraco.interfaces;
+using umbraco.uicontrols;
+using System.Linq;
+using BaseDataType = umbraco.editorControls.BaseDataType;
+
+namespace Umbraco.Tests
+{
+ [TestFixture]
+ public class DataTypeFactoryTests
+ {
+ [SetUp]
+ public void Initialize()
+ {
+ //for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
+ PluginTypeResolver.Current.AssembliesToScan = new[]
+ {
+ this.GetType().Assembly
+ };
+ }
+
+ [Test]
+ public void Find_All_DataTypes()
+ {
+ umbraco.cms.businesslogic.datatype.controls.Factory.Initialize();
+ Assert.AreEqual(2, umbraco.cms.businesslogic.datatype.controls.Factory._controls.Count);
+ }
+
+ [Test]
+ public void Get_All_Instances()
+ {
+ umbraco.cms.businesslogic.datatype.controls.Factory.Initialize();
+ var factory = new umbraco.cms.businesslogic.datatype.controls.Factory();
+ Assert.AreEqual(2, factory.GetAll().Count());
+ }
+
+ #region Classes for tests
+ public class DataType1 : AbstractDataEditor
+ {
+ public override Guid Id
+ {
+ get { return new Guid("FBAEA49B-F704-44FE-B725-6C8FE0767CF2"); }
+ }
+
+ public override string DataTypeName
+ {
+ get { return "DataType1"; }
+ }
+
+ public override IDataEditor DataEditor
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public override IDataPrevalue PrevalueEditor
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public override IData Data
+ {
+ get { throw new NotImplementedException(); }
+ }
+ }
+
+ public class DataType2 : AbstractDataEditor
+ {
+ public override Guid Id
+ {
+ get { return new Guid("3F58099B-96AC-415E-B3F9-BA273F51E681"); }
+ }
+
+ public override string DataTypeName
+ {
+ get { return "DataType2"; }
+ }
+
+ public override IDataEditor DataEditor
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public override IDataPrevalue PrevalueEditor
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public override IData Data
+ {
+ get { throw new NotImplementedException(); }
+ }
+ }
+ #endregion
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/EnumerableExtensionsTests.cs b/src/Umbraco.Tests/EnumerableExtensionsTests.cs
index 9bacfeb39a..c13cee8ea9 100644
--- a/src/Umbraco.Tests/EnumerableExtensionsTests.cs
+++ b/src/Umbraco.Tests/EnumerableExtensionsTests.cs
@@ -8,7 +8,6 @@ using Umbraco.Core.Resolving;
namespace Umbraco.Tests
{
-
[TestFixture]
public class EnumerableExtensionsTests
{
diff --git a/src/Umbraco.Tests/MacroControlFactoryTests.cs b/src/Umbraco.Tests/MacroControlFactoryTests.cs
new file mode 100644
index 0000000000..c70e24a599
--- /dev/null
+++ b/src/Umbraco.Tests/MacroControlFactoryTests.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Linq;
+using System.Web.UI;
+using NUnit.Framework;
+using Umbraco.Core;
+using umbraco.editorControls.macrocontainer;
+using umbraco.interfaces;
+
+namespace Umbraco.Tests
+{
+ [TestFixture]
+ public class MacroControlFactoryTests
+ {
+ [SetUp]
+ public void Initialize()
+ {
+ //for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
+ PluginTypeResolver.Current.AssembliesToScan = new[]
+ {
+ this.GetType().Assembly
+ };
+ }
+
+ [Test]
+ public void Find_Types()
+ {
+ var found = MacroControlFactory.MacroControlTypes;
+ Assert.AreEqual(2, found.Count());
+ }
+
+ #region Classes for tests
+ public class ControlMacroRendering : Control, IMacroGuiRendering
+ {
+ public string Value
+ {
+ get { throw new NotImplementedException(); }
+ set { throw new NotImplementedException(); }
+ }
+
+ public bool ShowCaption
+ {
+ get { throw new NotImplementedException(); }
+ }
+ }
+
+ public class NonControlMacroRendering : IMacroGuiRendering
+ {
+ public string Value
+ {
+ get { throw new NotImplementedException(); }
+ set { throw new NotImplementedException(); }
+ }
+
+ public bool ShowCaption
+ {
+ get { throw new NotImplementedException(); }
+ }
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/MacroEngineFactoryTests.cs b/src/Umbraco.Tests/MacroEngineFactoryTests.cs
new file mode 100644
index 0000000000..5c761d5291
--- /dev/null
+++ b/src/Umbraco.Tests/MacroEngineFactoryTests.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using NUnit.Framework;
+using Umbraco.Core;
+using umbraco.cms.businesslogic.macro;
+using umbraco.interfaces;
+
+namespace Umbraco.Tests
+{
+ [TestFixture]
+ public class MacroEngineFactoryTests
+ {
+ [SetUp]
+ public void Initialize()
+ {
+ //for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
+ PluginTypeResolver.Current.AssembliesToScan = new[]
+ {
+ this.GetType().Assembly
+ };
+ }
+
+ [Test]
+ public void Get_All()
+ {
+ var engines = MacroEngineFactory.GetAll();
+ Assert.AreEqual(2, engines.Count());
+ }
+
+ [Test]
+ public void Get_Engine()
+ {
+ var engine1 = MacroEngineFactory.GetEngine("MacroEngine1");
+ Assert.IsNotNull(engine1);
+ }
+
+ [Test]
+ public void Get_By_Filename()
+ {
+ var engine1 = MacroEngineFactory.GetByFilename("test.me1");
+ var engine2 = MacroEngineFactory.GetByFilename("test.me2");
+ Assert.IsNotNull(engine1);
+ Assert.IsNotNull(engine2);
+ Assert.Throws(() => MacroEngineFactory.GetByFilename("test.blah"));
+
+ }
+
+ [Test]
+ public void Get_By_Extension()
+ {
+ var engine1 = MacroEngineFactory.GetByExtension("me1");
+ var engine2 = MacroEngineFactory.GetByExtension("me2");
+ Assert.IsNotNull(engine1);
+ Assert.IsNotNull(engine2);
+ Assert.Throws(() => MacroEngineFactory.GetByExtension("blah"));
+ }
+
+ #region Classes for tests
+ public class MacroEngine1 : IMacroEngine
+ {
+ public string Name
+ {
+ get { return "MacroEngine1"; }
+ }
+
+ public IEnumerable SupportedExtensions
+ {
+ get { return new[] {"me1"}; }
+ }
+
+ public IEnumerable SupportedUIExtensions
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public Dictionary SupportedProperties
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public bool Validate(string code, string tempFileName, INode currentPage, out string errorMessage)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string Execute(MacroModel macro, INode currentPage)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public class MacroEngine2 : IMacroEngine
+ {
+ public string Name
+ {
+ get { return "MacroEngine2"; }
+ }
+
+ public IEnumerable SupportedExtensions
+ {
+ get { return new[] { "me2" }; }
+ }
+
+ public IEnumerable SupportedUIExtensions
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public Dictionary SupportedProperties
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public bool Validate(string code, string tempFileName, INode currentPage, out string errorMessage)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string Execute(MacroModel macro, INode currentPage)
+ {
+ throw new NotImplementedException();
+ }
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/MediaFactoryTests.cs b/src/Umbraco.Tests/MediaFactoryTests.cs
new file mode 100644
index 0000000000..b989ac8a28
--- /dev/null
+++ b/src/Umbraco.Tests/MediaFactoryTests.cs
@@ -0,0 +1,92 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using NUnit.Framework;
+using Umbraco.Core;
+using umbraco.BusinessLogic;
+using umbraco.cms.businesslogic.media;
+
+namespace Umbraco.Tests
+{
+ [TestFixture]
+ public class MediaFactoryTests
+ {
+ [SetUp]
+ public void Initialize()
+ {
+ //for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
+ PluginTypeResolver.Current.AssembliesToScan = new[]
+ {
+ this.GetType().Assembly
+ };
+ }
+
+ ///
+ /// Ensures that the media factory finds the correct number of IMediaFactory
+ ///
+ [Test]
+ public void Find_Media_Factories()
+ {
+ var factories = MediaFactory.Factories;
+ Assert.AreEqual(2, factories.Count());
+ }
+
+ #region Classes for tests
+ public class MediaFactory1 : IMediaFactory
+ {
+ public List Extensions
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public int Priority
+ {
+ get { return 1; }
+ }
+
+ public bool CanHandleMedia(int parentNodeId, PostedMediaFile postedFile, User user)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Media HandleMedia(int parentNodeId, PostedMediaFile postedFile, User user)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Media HandleMedia(int parentNodeId, PostedMediaFile postedFile, User user, bool replaceExisting)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public class MediaFactory2 : IMediaFactory
+ {
+ public List Extensions
+ {
+ get { throw new NotImplementedException(); }
+ }
+
+ public int Priority
+ {
+ get { return 2; }
+ }
+
+ public bool CanHandleMedia(int parentNodeId, PostedMediaFile postedFile, User user)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Media HandleMedia(int parentNodeId, PostedMediaFile postedFile, User user)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Media HandleMedia(int parentNodeId, PostedMediaFile postedFile, User user, bool replaceExisting)
+ {
+ throw new NotImplementedException();
+ }
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/PackageActionFactoryTests.cs b/src/Umbraco.Tests/PackageActionFactoryTests.cs
new file mode 100644
index 0000000000..a05e9764bb
--- /dev/null
+++ b/src/Umbraco.Tests/PackageActionFactoryTests.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Linq;
+using System.Xml;
+using NUnit.Framework;
+using Umbraco.Core;
+using umbraco.cms.businesslogic.packager;
+using umbraco.interfaces;
+
+namespace Umbraco.Tests
+{
+ [TestFixture]
+ public class PackageActionFactoryTests
+ {
+ [SetUp]
+ public void Initialize()
+ {
+ //for testing, we'll specify which assemblies are scanned for the PluginTypeResolver
+ PluginTypeResolver.Current.AssembliesToScan = new[]
+ {
+ this.GetType().Assembly
+ };
+ }
+
+ ///
+ /// Ensures all IPackageActions are found
+ ///
+ [Test]
+ public void Find_Package_Actions()
+ {
+ var actions = PackageAction.PackageActions;
+ Assert.AreEqual(2, actions.Count());
+ }
+
+ #region Classes for tests
+ public class PackageAction1 : IPackageAction
+ {
+ public bool Execute(string packageName, XmlNode xmlData)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string Alias()
+ {
+ return "pa1";
+ }
+
+ public bool Undo(string packageName, XmlNode xmlData)
+ {
+ throw new NotImplementedException();
+ }
+
+ public XmlNode SampleXml()
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public class PackageAction2 : IPackageAction
+ {
+ public bool Execute(string packageName, XmlNode xmlData)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string Alias()
+ {
+ return "pa2";
+ }
+
+ public bool Undo(string packageName, XmlNode xmlData)
+ {
+ throw new NotImplementedException();
+ }
+
+ public XmlNode SampleXml()
+ {
+ throw new NotImplementedException();
+ }
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/PluginTypeResolverTests.cs b/src/Umbraco.Tests/PluginTypeResolverTests.cs
index b9538191b7..058c71cb31 100644
--- a/src/Umbraco.Tests/PluginTypeResolverTests.cs
+++ b/src/Umbraco.Tests/PluginTypeResolverTests.cs
@@ -1,12 +1,51 @@
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.editorControls;
+using umbraco.uicontrols;
+using umbraco.cms;
namespace Umbraco.Tests
{
+
+ [TestFixture]
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,
+ typeof(BaseDataType).Assembly
+ };
+ }
+
[Test]
public void Ensure_Only_One_Type_List_Created()
{
@@ -22,6 +61,34 @@ 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());
+ }
+
+ [Test]
+ public void Resolves_Actions()
+ {
+ var types = PluginTypeResolver.Current.ResolveActions();
+ Assert.AreEqual(1, types.Count());
+ }
+
+ [Test]
+ public void Resolves_DataTypes()
+ {
+ var types = PluginTypeResolver.Current.ResolveDataTypes();
+ Assert.AreEqual(33, types.Count());
+ }
+
public interface IFindMe
{
diff --git a/src/Umbraco.Tests/TypeFinderBenchmarkTests.cs b/src/Umbraco.Tests/TypeFinderTests.cs
similarity index 85%
rename from src/Umbraco.Tests/TypeFinderBenchmarkTests.cs
rename to src/Umbraco.Tests/TypeFinderTests.cs
index 7ad7277ca6..2c61502a78 100644
--- a/src/Umbraco.Tests/TypeFinderBenchmarkTests.cs
+++ b/src/Umbraco.Tests/TypeFinderTests.cs
@@ -16,16 +16,15 @@ using umbraco.businesslogic;
using umbraco.cms.businesslogic;
using umbraco.uicontrols;
-[assembly: TypeFinderBenchmarkTests.AssemblyContainsPluginsAttribute]
+[assembly: TypeFinderTests.AssemblyContainsPluginsAttribute]
namespace Umbraco.Tests
{
///
/// Full Trust benchmark tests for typefinder and the old typefinder
///
- [TestFixture]
- [Ignore("This is a benchark test")]
- public class TypeFinderBenchmarkTests
+ [TestFixture]
+ public class TypeFinderTests
{
///
/// List of assemblies to scan
@@ -37,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,
@@ -73,18 +70,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(_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 +129,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 +156,7 @@ namespace Umbraco.Tests
/// cache files created instead since this is clearly a TON faster.
///
[Test]
+ [Ignore("This is a benchark test")]
public void Benchmark_Finding_First_Type_In_Assemblies()
{
var timer = new Stopwatch();
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index ae089775fd..6e02fd0446 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -49,6 +49,11 @@
+
+
+
+
+
@@ -62,7 +67,7 @@
-
+
@@ -92,6 +97,10 @@
{C7CB79F0-1C97-4B33-BFA7-00731B579AE2}
umbraco.datalayer
+
+ {255F5DF1-4E43-4758-AC05-7A0B68EB021B}
+ umbraco.editorControls
+
{511F6D8D-7717-440A-9A57-A507E9A8B27F}
umbraco.interfaces
diff --git a/src/Umbraco.Web/Routing/DocumentLookupsResolver.cs b/src/Umbraco.Web/Routing/DocumentLookupsResolver.cs
index 168c65eed7..fd2a021112 100644
--- a/src/Umbraco.Web/Routing/DocumentLookupsResolver.cs
+++ b/src/Umbraco.Web/Routing/DocumentLookupsResolver.cs
@@ -22,7 +22,7 @@ namespace Umbraco.Web.Routing
internal DocumentLookupsResolver(IEnumerable lookupTypes, IDocumentLastChanceLookup lastChanceLookup)
{
//TODO: I've changed this to resolve types but the intances are not created yet!
- // I've created a method on the PluginTypeResolver to create types: PluginTypesResolver.Current.CreateInstances()
+ // I've created a method on the PluginTypeResolver to create types: PluginTypesResolver.Current.FindAndCreateInstances()
_lookupTypes.AddRange(lookupsTypes);
diff --git a/src/umbraco.businesslogic/ApplicationRegistrar.cs b/src/umbraco.businesslogic/ApplicationRegistrar.cs
index d8ee358a93..29cd59ba37 100644
--- a/src/umbraco.businesslogic/ApplicationRegistrar.cs
+++ b/src/umbraco.businesslogic/ApplicationRegistrar.cs
@@ -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,11 +30,12 @@ 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()
- .Where(x => x.GetCustomAttributes(typeof(ApplicationAttribute), false).Any());
+ var types = PluginTypeResolver.Current.ResolveApplications();
- 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 924403820c..724ad770ba 100644
--- a/src/umbraco.businesslogic/PluginTypeResolverExtensions.cs
+++ b/src/umbraco.businesslogic/PluginTypeResolverExtensions.cs
@@ -20,5 +20,25 @@ namespace umbraco.businesslogic
return resolver.ResolveTypes();
}
+ ///
+ /// Returns all available IApplication in application
+ ///
+ ///
+ ///
+ internal static IEnumerable ResolveApplications(this PluginTypeResolver resolver)
+ {
+ 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
diff --git a/src/umbraco.cms/Actions/Action.cs b/src/umbraco.cms/Actions/Action.cs
index b7cae428d8..0622709b3b 100644
--- a/src/umbraco.cms/Actions/Action.cs
+++ b/src/umbraco.cms/Actions/Action.cs
@@ -6,6 +6,7 @@ using System.Reflection;
using Umbraco.Core;
using umbraco.BasePages;
using umbraco.BusinessLogic.Utils;
+using umbraco.cms;
using umbraco.cms.businesslogic.web;
using umbraco.cms.businesslogic.workflow;
using umbraco.interfaces;
@@ -35,9 +36,6 @@ namespace umbraco.BusinessLogic.Actions
private static readonly Dictionary ActionJs = new Dictionary();
private static readonly object Lock = new object();
- private static readonly object LockerReRegister = new object();
-
- private static readonly Umbraco.Core.TypeFinder2 TypeFinder = new TypeFinder2();
static Action()
{
@@ -64,17 +62,11 @@ namespace umbraco.BusinessLogic.Actions
///
private static void RegisterIActionHandlers()
{
-
if (ActionHandlers.Count == 0)
{
-
- var foundIActionHandlers = TypeFinder.FindClassesOfType();
- foreach (var type in foundIActionHandlers)
- {
- var typeInstance = Activator.CreateInstance(type) as IActionHandler;
- if (typeInstance != null)
- ActionHandlers.Add(typeInstance);
- }
+ ActionHandlers.AddRange(
+ PluginTypeResolver.Current.CreateInstances(
+ PluginTypeResolver.Current.ResolveActions()));
}
}
diff --git a/src/umbraco.cms/PluginTypeResolverExtensions.cs b/src/umbraco.cms/PluginTypeResolverExtensions.cs
new file mode 100644
index 0000000000..3588a855dc
--- /dev/null
+++ b/src/umbraco.cms/PluginTypeResolverExtensions.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using Umbraco.Core;
+using umbraco.BusinessLogic.Actions;
+using umbraco.businesslogic;
+using umbraco.cms.businesslogic.macro;
+using umbraco.cms.businesslogic.media;
+using umbraco.interfaces;
+
+namespace umbraco.cms
+{
+ ///
+ /// Extension methods for the PluginTypeResolver
+ ///
+ public static class PluginTypeResolverExtensions
+ {
+
+ ///
+ /// Returns all available IActionHandler in application
+ ///
+ ///
+ ///
+ internal static IEnumerable ResolveActions(this PluginTypeResolver resolver)
+ {
+ return resolver.ResolveTypes();
+ }
+
+ ///
+ /// Returns all available IDataType in application
+ ///
+ ///
+ ///
+ internal static IEnumerable ResolveDataTypes(this PluginTypeResolver resolver)
+ {
+ return resolver.ResolveTypes();
+ }
+
+ ///
+ /// Returns all available IDataType in application
+ ///
+ ///
+ ///
+ internal static IEnumerable ResolveMacroEngines(this PluginTypeResolver resolver)
+ {
+ return resolver.ResolveTypes();
+ }
+
+ ///
+ /// Returns all available IMediaFactory in application
+ ///
+ ///
+ ///
+ internal static IEnumerable ResolveMediaFactories(this PluginTypeResolver resolver)
+ {
+ return resolver.ResolveTypes();
+ }
+
+ ///
+ /// Returns all available IPackageAction in application
+ ///
+ ///
+ ///
+ internal static IEnumerable ResolvePackageActions(this PluginTypeResolver resolver)
+ {
+ return resolver.ResolveTypes();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/umbraco.cms/Properties/AssemblyInfo.cs b/src/umbraco.cms/Properties/AssemblyInfo.cs
index c38a6bd99c..9cbdba2843 100644
--- a/src/umbraco.cms/Properties/AssemblyInfo.cs
+++ b/src/umbraco.cms/Properties/AssemblyInfo.cs
@@ -13,4 +13,5 @@ using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("umbraco", AllInternalsVisible=true)]
-[assembly: InternalsVisibleTo("Umbraco.LegacyTests")]
\ No newline at end of file
+[assembly: InternalsVisibleTo("Umbraco.LegacyTests")]
+[assembly: InternalsVisibleTo("Umbraco.Tests")]
\ No newline at end of file
diff --git a/src/umbraco.cms/businesslogic/Packager/PackageInstance/PackageActions.cs b/src/umbraco.cms/businesslogic/Packager/PackageInstance/PackageActions.cs
index 36f24a918e..151de71d00 100644
--- a/src/umbraco.cms/businesslogic/Packager/PackageInstance/PackageActions.cs
+++ b/src/umbraco.cms/businesslogic/Packager/PackageInstance/PackageActions.cs
@@ -3,7 +3,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Xml;
-
+using Umbraco.Core;
using umbraco.BasePages;
using umbraco.BusinessLogic.Utils;
using umbraco.cms.businesslogic.web;
@@ -11,79 +11,84 @@ using umbraco.cms.businesslogic.workflow;
using umbraco.interfaces;
-namespace umbraco.cms.businesslogic.packager {
+namespace umbraco.cms.businesslogic.packager
+{
- ///
- /// Package actions are executed on packge install / uninstall.
- ///
- public class PackageAction {
- private static readonly List _packageActions = new List();
+ ///
+ /// Package actions are executed on packge install / uninstall.
+ ///
+ public class PackageAction
+ {
+ internal static readonly List PackageActions = new List();
- ///
- /// Initializes the class.
- ///
- static PackageAction(){
- RegisterPackageActions();
- }
-
- private static void RegisterPackageActions()
- {
- var typeFinder = new Umbraco.Core.TypeFinder2();
- var types = typeFinder.FindClassesOfType();
- foreach (var t in types)
- {
- var typeInstance = Activator.CreateInstance(t) as IPackageAction;
- if (typeInstance != null)
- {
- _packageActions.Add(typeInstance);
-
- if (HttpContext.Current != null)
- HttpContext.Current.Trace.Write("registerPackageActions", " + Adding package action '" + typeInstance.Alias());
- }
- }
- }
+ ///
+ /// Initializes the class.
+ ///
+ static PackageAction()
+ {
+ RegisterPackageActions();
+ }
- ///
- /// Runs the package action with the specified action alias.
- ///
- /// Name of the package.
- /// The action alias.
- /// The action XML.
- public static void RunPackageAction(string packageName, string actionAlias, System.Xml.XmlNode actionXml) {
+ private static void RegisterPackageActions()
+ {
+ PackageActions.AddRange(
+ PluginTypeResolver.Current.CreateInstances(
+ PluginTypeResolver.Current.ResolvePackageActions()));
+ }
- foreach (IPackageAction ipa in _packageActions) {
- try {
- if (ipa.Alias() == actionAlias) {
+ ///
+ /// Runs the package action with the specified action alias.
+ ///
+ /// Name of the package.
+ /// The action alias.
+ /// The action XML.
+ public static void RunPackageAction(string packageName, string actionAlias, System.Xml.XmlNode actionXml)
+ {
- ipa.Execute(packageName, actionXml);
- }
- } catch (Exception ipaExp) {
- BusinessLogic.Log.Add(BusinessLogic.LogTypes.Error, BusinessLogic.User.GetUser(0), -1, string.Format("Error loading package action '{0}' for package {1}: {2}",
- ipa.Alias(), packageName, ipaExp));
- }
- }
- }
+ foreach (IPackageAction ipa in PackageActions)
+ {
+ try
+ {
+ if (ipa.Alias() == actionAlias)
+ {
- ///
- /// Undos the package action with the specified action alias.
- ///
- /// Name of the package.
- /// The action alias.
- /// The action XML.
- public static void UndoPackageAction(string packageName, string actionAlias, System.Xml.XmlNode actionXml) {
+ ipa.Execute(packageName, actionXml);
+ }
+ }
+ catch (Exception ipaExp)
+ {
+ BusinessLogic.Log.Add(BusinessLogic.LogTypes.Error, BusinessLogic.User.GetUser(0), -1, string.Format("Error loading package action '{0}' for package {1}: {2}",
+ ipa.Alias(), packageName, ipaExp));
+ }
+ }
+ }
- foreach (IPackageAction ipa in _packageActions) {
- try {
- if (ipa.Alias() == actionAlias) {
+ ///
+ /// Undos the package action with the specified action alias.
+ ///
+ /// Name of the package.
+ /// The action alias.
+ /// The action XML.
+ public static void UndoPackageAction(string packageName, string actionAlias, System.Xml.XmlNode actionXml)
+ {
- ipa.Undo(packageName, actionXml);
- }
- } catch (Exception ipaExp) {
- BusinessLogic.Log.Add(BusinessLogic.LogTypes.Error, BusinessLogic.User.GetUser(0), -1, string.Format("Error undoing package action '{0}' for package {1}: {2}",
- ipa.Alias(), packageName, ipaExp));
- }
- }
- }
-
- }
+ foreach (IPackageAction ipa in PackageActions)
+ {
+ try
+ {
+ if (ipa.Alias() == actionAlias)
+ {
+
+ ipa.Undo(packageName, actionXml);
+ }
+ }
+ catch (Exception ipaExp)
+ {
+ BusinessLogic.Log.Add(BusinessLogic.LogTypes.Error, BusinessLogic.User.GetUser(0), -1, string.Format("Error undoing package action '{0}' for package {1}: {2}",
+ ipa.Alias(), packageName, ipaExp));
+ }
+ }
+ }
+
+ }
}
diff --git a/src/umbraco.cms/businesslogic/datatype/factory.cs b/src/umbraco.cms/businesslogic/datatype/factory.cs
index 617c6bf093..240742cddd 100644
--- a/src/umbraco.cms/businesslogic/datatype/factory.cs
+++ b/src/umbraco.cms/businesslogic/datatype/factory.cs
@@ -1,7 +1,9 @@
using System;
using System.Collections;
+using System.Collections.Concurrent;
+using System.Linq;
using System.Web;
-
+using Umbraco.Core;
using umbraco.BusinessLogic.Utils;
using umbraco.interfaces;
using System.Collections.Generic;
@@ -17,7 +19,7 @@ namespace umbraco.cms.businesslogic.datatype.controls
{
#region Declarations
- private static readonly Dictionary _controls = new Dictionary();
+ internal static readonly ConcurrentDictionary _controls = new ConcurrentDictionary();
#endregion
@@ -53,7 +55,7 @@ namespace umbraco.cms.businesslogic.datatype.controls
}
if (_controls.ContainsKey(DataEditorId))
{
- IDataType newObject = Activator.CreateInstance(_controls[DataEditorId]) as IDataType;
+ var newObject = PluginTypeResolver.Current.CreateInstance(_controls[DataEditorId]);
return newObject;
}
else
@@ -68,10 +70,10 @@ namespace umbraco.cms.businesslogic.datatype.controls
/// A list of IDataType's
public IDataType[] GetAll()
{
- IDataType[] retVal = new IDataType[_controls.Count];
- int c = 0;
+ var retVal = new IDataType[_controls.Count];
+ var c = 0;
- foreach (Guid id in _controls.Keys)
+ foreach (var id in _controls.Keys)
{
retVal[c] = GetNewObject(id);
c++;
@@ -80,39 +82,19 @@ namespace umbraco.cms.businesslogic.datatype.controls
return retVal;
}
- private static void Initialize()
+ internal static void Initialize()
{
// Get all datatypes from interface
- var typeFinder = new Umbraco.Core.TypeFinder2();
- var types = typeFinder.FindClassesOfType();
- GetDataTypes(types);
- }
-
- private static void GetDataTypes(IEnumerable types)
- {
- foreach (var t in types)
- {
- IDataType typeInstance = null;
- try
- {
- if (t.IsVisible)
- {
- typeInstance = Activator.CreateInstance(t) as IDataType;
- }
- }
- catch { }
- if (typeInstance != null)
- {
- try
- {
- _controls.Add(typeInstance.Id, t);
- }
- catch (Exception ee)
- {
- BusinessLogic.Log.Add(umbraco.BusinessLogic.LogTypes.Error, -1, "Can't import datatype '" + t.FullName + "': " + ee.ToString());
- }
- }
- }
+ var types = PluginTypeResolver.Current.ResolveDataTypes().ToArray();
+ foreach (var t in types)
+ {
+ var instance = PluginTypeResolver.Current.CreateInstance(t);
+ if (instance != null)
+ {
+ _controls.TryAdd(instance.Id, t);
+ }
+ }
}
+
}
}
\ No newline at end of file
diff --git a/src/umbraco.cms/businesslogic/macro/MacroEngineFactory.cs b/src/umbraco.cms/businesslogic/macro/MacroEngineFactory.cs
index 506c1a2d51..fe5406c76c 100644
--- a/src/umbraco.cms/businesslogic/macro/MacroEngineFactory.cs
+++ b/src/umbraco.cms/businesslogic/macro/MacroEngineFactory.cs
@@ -1,59 +1,50 @@
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using System.Threading;
+using Umbraco.Core;
using umbraco.BusinessLogic.Utils;
using umbraco.interfaces;
namespace umbraco.cms.businesslogic.macro
{
+
+ //TODO: This class needs to be changed to use the new MultipleResolverBase
+
public class MacroEngineFactory
{
- private static readonly Dictionary m_engines = new Dictionary();
- private static readonly List m_allEngines = new List();
- private static object locker = new object();
+ private static readonly List AllEngines = new List();
+ private static readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim();
+ private static volatile bool _isInitialized = false;
public MacroEngineFactory()
{
- Initialize();
+ EnsureInitialize();
}
+ internal static void EnsureInitialize()
+ {
+ if (_isInitialized)
+ return;
+
+ using (new WriteLock(Lock))
+ {
+ AllEngines.Clear();
+
+ AllEngines.AddRange(
+ PluginTypeResolver.Current.CreateInstances(
+ PluginTypeResolver.Current.ResolveMacroEngines()));
+
+ _isInitialized = true;
+ }
+ }
+
+ [Obsolete("Use EnsureInitialize method instead")]
protected static void Initialize()
{
- var typeFinder = new Umbraco.Core.TypeFinder2();
- var types = typeFinder.FindClassesOfType();
- GetEngines(types);
- }
-
- private static void GetEngines(IEnumerable types)
- {
- foreach (Type t in types)
- {
- IMacroEngine typeInstance = null;
- try
- {
- if (t.IsVisible)
- {
- typeInstance = Activator.CreateInstance(t) as IMacroEngine;
- }
- }
- catch { }
- if (typeInstance != null)
- {
- try
- {
- lock (locker)
- {
- if (!m_engines.ContainsKey(typeInstance.Name))
- m_engines.Add(typeInstance.Name, t);
- }
- }
- catch (Exception ee)
- {
- BusinessLogic.Log.Add(umbraco.BusinessLogic.LogTypes.Error, -1, "Can't import MacroEngine '" + t.FullName + "': " + ee);
- }
- }
- }
+ EnsureInitialize();
}
public static IEnumerable GetSupportedLanguages() {
@@ -78,27 +69,15 @@ namespace umbraco.cms.businesslogic.macro
public static List GetAll()
{
-
- if (m_allEngines.Count == 0)
- {
- Initialize();
- foreach (string name in m_engines.Keys) {
- m_allEngines.Add(GetEngine(name));
- }
- }
-
- return m_allEngines;
+ EnsureInitialize();
+ return AllEngines;
}
public static IMacroEngine GetEngine(string name)
{
- if (m_engines.ContainsKey(name))
- {
- var newObject = Activator.CreateInstance(m_engines[name]) as IMacroEngine;
- return newObject;
- }
-
- return null;
+ EnsureInitialize();
+ var engine = AllEngines.FirstOrDefault(x => x.Name == name);
+ return engine;
}
public static IMacroEngine GetByFilename(string filename)
@@ -114,8 +93,7 @@ namespace umbraco.cms.businesslogic.macro
public static IMacroEngine GetByExtension(string extension)
{
- IMacroEngine engine =
- GetAll().Find(t => t.SupportedExtensions.Contains(extension));
+ var engine = GetAll().Find(t => t.SupportedExtensions.Contains(extension));
if (engine != null)
{
return engine;
diff --git a/src/umbraco.cms/businesslogic/media/MediaFactory.cs b/src/umbraco.cms/businesslogic/media/MediaFactory.cs
index f11bf97d0b..da9154549d 100644
--- a/src/umbraco.cms/businesslogic/media/MediaFactory.cs
+++ b/src/umbraco.cms/businesslogic/media/MediaFactory.cs
@@ -3,14 +3,17 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
+using Umbraco.Core;
using umbraco.BusinessLogic;
using umbraco.BusinessLogic.Utils;
namespace umbraco.cms.businesslogic.media
{
+ //TODO: This class needs to inherit from the new MultipleResolverBase class
+
public class MediaFactory
{
- private static readonly List Factories = new List();
+ internal static readonly List Factories = new List();
static MediaFactory()
{
@@ -19,36 +22,11 @@ namespace umbraco.cms.businesslogic.media
private static void Initialize()
{
- var typeFinder = new Umbraco.Core.TypeFinder2();
- var types = typeFinder.FindClassesOfType();
-
- foreach (var t in types)
- {
- IMediaFactory typeInstance = null;
-
- try
- {
- if (t.IsVisible)
- {
- typeInstance = Activator.CreateInstance(t) as IMediaFactory;
- }
- }
- catch { }
-
- if (typeInstance != null)
- {
- try
- {
- Factories.Add(typeInstance);
- }
- catch (Exception ee)
- {
- Log.Add(LogTypes.Error, -1, "Can't import MediaFactory '" + t.FullName + "': " + ee);
- }
- }
- }
-
- Factories.Sort((f1, f2) => f1.Priority.CompareTo(f2.Priority));
+ Factories.AddRange(
+ PluginTypeResolver.Current.CreateInstances(
+ PluginTypeResolver.Current.ResolveMediaFactories()));
+
+ Factories.Sort((f1, f2) => f1.Priority.CompareTo(f2.Priority));
}
public static IMediaFactory GetMediaFactory(int parentId, PostedMediaFile postedFile, User user)
diff --git a/src/umbraco.cms/umbraco.cms.csproj b/src/umbraco.cms/umbraco.cms.csproj
index 068836f738..bdd3b9639d 100644
--- a/src/umbraco.cms/umbraco.cms.csproj
+++ b/src/umbraco.cms/umbraco.cms.csproj
@@ -267,6 +267,7 @@
+
Code
diff --git a/src/umbraco.editorControls/PluginTypeResolverExtensions.cs b/src/umbraco.editorControls/PluginTypeResolverExtensions.cs
new file mode 100644
index 0000000000..ae557087a1
--- /dev/null
+++ b/src/umbraco.editorControls/PluginTypeResolverExtensions.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using Umbraco.Core;
+using umbraco.BusinessLogic.Actions;
+using umbraco.cms.businesslogic.macro;
+using umbraco.cms.businesslogic.media;
+using umbraco.interfaces;
+
+namespace umbraco.editorControls
+{
+ ///
+ /// Extension methods for the PluginTypeResolver
+ ///
+ public static class PluginTypeResolverExtensions
+ {
+
+ ///
+ /// Returns all available IMacroGuiRendering in application
+ ///
+ ///
+ ///
+ internal static IEnumerable ResolveMacroRenderings(this PluginTypeResolver resolver)
+ {
+ return resolver.ResolveTypes();
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/src/umbraco.editorControls/Properties/AssemblyInfo.cs b/src/umbraco.editorControls/Properties/AssemblyInfo.cs
index 15de1fa37b..e84fc669e0 100644
--- a/src/umbraco.editorControls/Properties/AssemblyInfo.cs
+++ b/src/umbraco.editorControls/Properties/AssemblyInfo.cs
@@ -10,3 +10,5 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyProduct("")]
+
+[assembly: InternalsVisibleTo("Umbraco.Tests")]
\ No newline at end of file
diff --git a/src/umbraco.editorControls/macrocontainer/MacroControlFactory.cs b/src/umbraco.editorControls/macrocontainer/MacroControlFactory.cs
index e7b7ff1f6a..da2b1d301b 100644
--- a/src/umbraco.editorControls/macrocontainer/MacroControlFactory.cs
+++ b/src/umbraco.editorControls/macrocontainer/MacroControlFactory.cs
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using System.Web.UI;
+using Umbraco.Core;
using umbraco.BusinessLogic.Utils;
using umbraco.interfaces;
using umbraco.editorControls;
@@ -12,14 +14,17 @@ namespace umbraco.editorControls.macrocontainer
{
internal class MacroControlFactory
{
- #region Private Fields
+
///
/// All Possible Macro types
///
private static List _macroControlTypes = null;
- #endregion
+
+ private static readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim();
+
#region Methods
+
///
/// Create an instance of a Macro control and return it.
/// Because the macro control uses inline client script whichs is not generated after postback
@@ -27,19 +32,22 @@ namespace umbraco.editorControls.macrocontainer
///
internal static Control GetMacroRenderControlByType(PersistableMacroProperty prop, string uniqueID)
{
- Control macroControl;
-
- Type m = MacroControlTypes.FindLast(delegate(Type macroGuiCcontrol) { return macroGuiCcontrol.ToString() == string.Format("{0}.{1}", prop.AssemblyName, prop.TypeName); });
- IMacroGuiRendering typeInstance;
- typeInstance = Activator.CreateInstance(m) as IMacroGuiRendering;
- if (!string.IsNullOrEmpty(prop.Value))
- {
- ((IMacroGuiRendering)typeInstance).Value = prop.Value;
- }
- macroControl = (Control)typeInstance;
-
- macroControl.ID = uniqueID;
- return macroControl;
+ var m = MacroControlTypes.FindLast(macroGuiCcontrol => macroGuiCcontrol.ToString() == string.Format("{0}.{1}", prop.AssemblyName, prop.TypeName));
+ var instance = PluginTypeResolver.Current.CreateInstance(m);
+ if (instance != null)
+ {
+ if (!string.IsNullOrEmpty(prop.Value))
+ {
+ instance.Value = prop.Value;
+ }
+ var macroControl = instance as Control;
+ if (macroControl != null)
+ {
+ macroControl.ID = uniqueID;
+ return macroControl;
+ }
+ }
+ return null;
}
///
@@ -51,25 +59,29 @@ namespace umbraco.editorControls.macrocontainer
{
return ((IMacroGuiRendering)macroControl).Value;
}
+
#endregion
#region Properties
///
/// All Possible Macro types
///
- private static List MacroControlTypes
+ internal static List MacroControlTypes
{
get
{
- if (_macroControlTypes == null || !_macroControlTypes.Any())
- {
- //Populate the list with all the types of IMacroGuiRendering
- var typeFinder = new Umbraco.Core.TypeFinder2();
- _macroControlTypes = new List();
- _macroControlTypes = typeFinder.FindClassesOfType().ToList();
- }
+ using (var readLock = new UpgradeableReadLock(Lock))
+ {
+ if (_macroControlTypes == null || !_macroControlTypes.Any())
+ {
- return _macroControlTypes;
+ readLock.UpgradeToWriteLock();
+
+ _macroControlTypes = new List(PluginTypeResolver.Current.ResolveMacroRenderings());
+ }
+
+ return _macroControlTypes;
+ }
}
}
#endregion
diff --git a/src/umbraco.editorControls/umbraco.editorControls.csproj b/src/umbraco.editorControls/umbraco.editorControls.csproj
index cfdcd26b37..e3a392ee94 100644
--- a/src/umbraco.editorControls/umbraco.editorControls.csproj
+++ b/src/umbraco.editorControls/umbraco.editorControls.csproj
@@ -176,6 +176,7 @@
+
Code