diff --git a/src/Umbraco.Core/PluginTypeResolver.cs b/src/Umbraco.Core/PluginTypeResolver.cs
index 50df96c5c2..8440aadb02 100644
--- a/src/Umbraco.Core/PluginTypeResolver.cs
+++ b/src/Umbraco.Core/PluginTypeResolver.cs
@@ -104,6 +104,19 @@ namespace Umbraco.Core
return instances;
}
+ ///
+ /// Used to create an instance of the specified type based on the resolved/cached plugin types
+ ///
+ ///
+ ///
+ ///
+ ///
+ 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))
diff --git a/src/Umbraco.Core/Resolving/MultipleResolverBase.cs b/src/Umbraco.Core/Resolving/MultipleResolverBase.cs
index 8fba742f58..85104696f0 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 to return and set a Multiply registered object.
///
diff --git a/src/Umbraco.Tests/DataTypeFactoryTests.cs b/src/Umbraco.Tests/DataTypeFactoryTests.cs
new file mode 100644
index 0000000000..46f0cedd7a
--- /dev/null
+++ b/src/Umbraco.Tests/DataTypeFactoryTests.cs
@@ -0,0 +1,63 @@
+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 System.Linq;
+
+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,
+ 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 Find_All_DataTypes()
+ {
+ umbraco.cms.businesslogic.datatype.controls.Factory.Initialize();
+ Assert.AreEqual(33, 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(33, factory.GetAll().Count());
+ }
+
+ }
+}
\ 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/PluginTypeResolverTests.cs b/src/Umbraco.Tests/PluginTypeResolverTests.cs
index 96e0ede87a..058c71cb31 100644
--- a/src/Umbraco.Tests/PluginTypeResolverTests.cs
+++ b/src/Umbraco.Tests/PluginTypeResolverTests.cs
@@ -8,6 +8,7 @@ using umbraco.MacroEngines;
using umbraco.MacroEngines.Iron;
using umbraco.businesslogic;
using umbraco.cms.businesslogic;
+using umbraco.editorControls;
using umbraco.uicontrols;
using umbraco.cms;
@@ -40,8 +41,8 @@ namespace Umbraco.Tests
typeof(ISqlHelper).Assembly,
typeof(DLRScriptingEngine).Assembly,
typeof(ICultureDictionary).Assembly,
- typeof(UmbracoContext).Assembly
-
+ typeof(UmbracoContext).Assembly,
+ typeof(BaseDataType).Assembly
};
}
@@ -81,6 +82,13 @@ namespace Umbraco.Tests
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/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index ae089775fd..d00037beb8 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -49,6 +49,7 @@
+
@@ -92,6 +93,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.cms/PluginTypeResolverExtensions.cs b/src/umbraco.cms/PluginTypeResolverExtensions.cs
index 1ccda0c54d..6b5c56f1f5 100644
--- a/src/umbraco.cms/PluginTypeResolverExtensions.cs
+++ b/src/umbraco.cms/PluginTypeResolverExtensions.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using Umbraco.Core;
using umbraco.BusinessLogic.Actions;
using umbraco.businesslogic;
+using umbraco.cms.businesslogic.macro;
using umbraco.interfaces;
namespace umbraco.cms
@@ -23,5 +24,25 @@ namespace umbraco.cms
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();
+ }
+
}
}
\ No newline at end of file
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;