Obsoletes umbraco.cms.businesslogic.datatype.controls.Factory with new Umbraco.Core.DataTypesResolver
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Umbraco.Core.Resolving;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
internal sealed class CacheRefreshersResolver : ManyObjectResolverBase<ICacheRefresher>
|
||||
/// <summary>
|
||||
/// A resolver to return all ICacheRefresher objects
|
||||
/// </summary>
|
||||
internal sealed class CacheRefreshersResolver : LegacyTransientObjectsResolver<ICacheRefresher>
|
||||
{
|
||||
|
||||
#region Singleton
|
||||
@@ -28,29 +28,14 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="refreshers"></param>
|
||||
/// <remarks>
|
||||
/// We are creating Transient instances (new instances each time) because this is how the legacy code worked and
|
||||
/// I don't want to muck anything up by changing them to application based instances.
|
||||
/// TODO: However, it would make much more sense to do this and would speed up the application plus this would make the GetById method much easier.
|
||||
/// </remarks>
|
||||
/// <param name="refreshers"></param>
|
||||
internal CacheRefreshersResolver(IEnumerable<Type> refreshers)
|
||||
: base(true)
|
||||
: base(refreshers)
|
||||
{
|
||||
foreach (var l in refreshers)
|
||||
{
|
||||
this.Add(l);
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Maintains a list of Ids and their types when first call to CacheResolvers or GetById occurs, this is used
|
||||
/// in order to return a single object by id without instantiating the entire type stack.
|
||||
/// </summary>
|
||||
private static ConcurrentDictionary<Guid, Type> _refreshers;
|
||||
private readonly ReaderWriterLockSlim _lock= new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ICacheRefresher"/> implementations.
|
||||
/// </summary>
|
||||
@@ -63,37 +48,9 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new ICacheRefresher instance by id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public ICacheRefresher GetById(Guid id)
|
||||
protected override Guid GetUniqueIdentifier(ICacheRefresher obj)
|
||||
{
|
||||
EnsureRefreshersList();
|
||||
return !_refreshers.ContainsKey(id)
|
||||
? null
|
||||
: PluginTypeResolver.Current.CreateInstance<ICacheRefresher>(_refreshers[id]);
|
||||
return obj.UniqueIdentifier;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates the refreshers dictionary to allow us to instantiate a type by Id since the ICacheRefresher type doesn't contain any metadata
|
||||
/// </summary>
|
||||
private void EnsureRefreshersList()
|
||||
{
|
||||
using (var l = new UpgradeableReadLock(_lock))
|
||||
{
|
||||
if (_refreshers == null)
|
||||
{
|
||||
l.UpgradeToWriteLock();
|
||||
_refreshers = new ConcurrentDictionary<Guid, Type>();
|
||||
foreach(var v in Values)
|
||||
{
|
||||
_refreshers.TryAdd(v.UniqueIdentifier, v.GetType());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
54
src/Umbraco.Core/DataTypesResolver.cs
Normal file
54
src/Umbraco.Core/DataTypesResolver.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A resolver to return all IDataType objects
|
||||
/// </summary>
|
||||
internal sealed class DataTypesResolver : LegacyTransientObjectsResolver<IDataType>
|
||||
{
|
||||
|
||||
#region Singleton
|
||||
|
||||
private static readonly DataTypesResolver Instance = new DataTypesResolver(PluginTypeResolver.Current.ResolveDataTypes());
|
||||
|
||||
public static DataTypesResolver Current
|
||||
{
|
||||
get { return Instance; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
static DataTypesResolver() { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="dataTypes"></param>
|
||||
internal DataTypesResolver(IEnumerable<Type> dataTypes)
|
||||
: base(dataTypes)
|
||||
{
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ICacheRefresher"/> implementations.
|
||||
/// </summary>
|
||||
public IEnumerable<IDataType> DataTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureRefreshersList();
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
|
||||
protected override Guid GetUniqueIdentifier(IDataType obj)
|
||||
{
|
||||
return obj.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
91
src/Umbraco.Core/LegacyTransientObjectsResolver.cs
Normal file
91
src/Umbraco.Core/LegacyTransientObjectsResolver.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Umbraco.Core.Resolving;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A base resolver used for old legacy factories such as the DataTypeFactory or CacheResolverFactory.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <remarks>
|
||||
/// This class contains basic functionality to mimic the functionality in these old factories since they all return
|
||||
/// transient objects (though this should be changed) and the method GetById needs to lookup a type to an ID and since
|
||||
/// these old classes don't contain metadata, the objects need to be instantiated first to get their metadata, we then store this
|
||||
/// for use in the GetById method.
|
||||
/// </remarks>
|
||||
internal abstract class LegacyTransientObjectsResolver<T> : ManyObjectResolverBase<T>
|
||||
where T : class
|
||||
{
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="refreshers"></param>
|
||||
/// <remarks>
|
||||
/// We are creating Transient instances (new instances each time) because this is how the legacy code worked and
|
||||
/// I don't want to muck anything up by changing them to application based instances.
|
||||
/// TODO: However, it would make much more sense to do this and would speed up the application plus this would make the GetById method much easier.
|
||||
/// </remarks>
|
||||
protected LegacyTransientObjectsResolver(IEnumerable<Type> refreshers)
|
||||
: base(true)
|
||||
{
|
||||
foreach (var l in refreshers)
|
||||
{
|
||||
this.Add(l);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Maintains a list of Ids and their types when first call to CacheResolvers or GetById occurs, this is used
|
||||
/// in order to return a single object by id without instantiating the entire type stack.
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<Guid, Type> _trackIdToType;
|
||||
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// method to return the unique id for type T
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
protected abstract Guid GetUniqueIdentifier(T obj);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new ICacheRefresher instance by id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public T GetById(Guid id)
|
||||
{
|
||||
EnsureRefreshersList();
|
||||
return !_trackIdToType.ContainsKey(id)
|
||||
? null
|
||||
: PluginTypeResolver.Current.CreateInstance<T>(_trackIdToType[id]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates the refreshers dictionary to allow us to instantiate a type by Id since the ICacheRefresher type doesn't contain any metadata
|
||||
/// </summary>
|
||||
protected void EnsureRefreshersList()
|
||||
{
|
||||
using (var l = new UpgradeableReadLock(_lock))
|
||||
{
|
||||
if (_trackIdToType == null)
|
||||
{
|
||||
l.UpgradeToWriteLock();
|
||||
_trackIdToType = new ConcurrentDictionary<Guid, Type>();
|
||||
foreach (var v in Values)
|
||||
{
|
||||
_trackIdToType.TryAdd(GetUniqueIdentifier(v), v.GetType());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,15 @@ namespace Umbraco.Core
|
||||
return ResolveTypes<ICacheRefresher>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all available IDataType in application
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<Type> ResolveDataTypes()
|
||||
{
|
||||
return ResolveTypes<IDataType>();
|
||||
}
|
||||
|
||||
/// <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.
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
<Compile Include="Configuration\GlobalSettings.cs" />
|
||||
<Compile Include="Configuration\UmbracoSettings.cs" />
|
||||
<Compile Include="CustomBooleanTypeConverter.cs" />
|
||||
<Compile Include="DataTypesResolver.cs" />
|
||||
<Compile Include="DisposableObject.cs" />
|
||||
<Compile Include="DisposableTimer.cs" />
|
||||
<Compile Include="ExpressionHelper.cs" />
|
||||
@@ -63,6 +64,7 @@
|
||||
<Compile Include="IO\SystemDirectories.cs" />
|
||||
<Compile Include="IO\SystemFiles.cs" />
|
||||
<Compile Include="LambdaExpressionCacheKey.cs" />
|
||||
<Compile Include="LegacyTransientObjectsResolver.cs" />
|
||||
<Compile Include="Logging\AsynchronousRollingFileAppender.cs" />
|
||||
<Compile Include="Logging\LoggingTaskExtension.cs" />
|
||||
<Compile Include="Logging\LogHelper.cs" />
|
||||
|
||||
@@ -26,13 +26,6 @@ namespace Umbraco.Tests
|
||||
};
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Find_All_DataTypes()
|
||||
{
|
||||
var factory = new umbraco.cms.businesslogic.datatype.controls.Factory();
|
||||
Assert.AreEqual(2, umbraco.cms.businesslogic.datatype.controls.Factory._controls.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_All_Instances()
|
||||
{
|
||||
|
||||
@@ -35,16 +35,6 @@ namespace umbraco.cms
|
||||
return resolver.ResolveTypes<IAction>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all available IDataType in application
|
||||
/// </summary>
|
||||
/// <param name="resolver"></param>
|
||||
/// <returns></returns>
|
||||
internal static IEnumerable<Type> ResolveDataTypes(this PluginTypeResolver resolver)
|
||||
{
|
||||
return resolver.ResolveTypes<IDataType>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all available IDataType in application
|
||||
/// </summary>
|
||||
|
||||
@@ -15,22 +15,9 @@ namespace umbraco.cms.businesslogic.datatype.controls
|
||||
///
|
||||
/// Then registering is done using reflection.
|
||||
/// </summary>
|
||||
[Obsolete("Use Umbraco.Core.DataTypesResolver instead")]
|
||||
public class Factory
|
||||
{
|
||||
#region Declarations
|
||||
|
||||
internal static readonly ConcurrentDictionary<Guid, Type> _controls = new ConcurrentDictionary<Guid, Type>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
static Factory()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
#endregion
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the IDataType specified by it's unique ID
|
||||
@@ -49,19 +36,7 @@ namespace umbraco.cms.businesslogic.datatype.controls
|
||||
/// <returns></returns>
|
||||
public IDataType GetNewObject(Guid DataEditorId)
|
||||
{
|
||||
if (DataEditorId == Guid.Empty)
|
||||
{
|
||||
throw new ArgumentException("DataEditorId is empty. This usually means that no data editor was defined for the data type. To correct this update the entry in the cmsDataType table to ensure it matches a Guid from an installed data editor.");
|
||||
}
|
||||
if (_controls.ContainsKey(DataEditorId))
|
||||
{
|
||||
var newObject = PluginTypeResolver.Current.CreateInstance<IDataType>(_controls[DataEditorId]);
|
||||
return newObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Could not find a IDataType control matching DataEditorId " + DataEditorId.ToString() + " in the controls collection. To correct this, check the data type definition in the developer section or ensure that the package/control is installed correctly.");
|
||||
}
|
||||
return DataTypesResolver.Current.GetById(DataEditorId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -70,31 +45,9 @@ namespace umbraco.cms.businesslogic.datatype.controls
|
||||
/// <returns>A list of IDataType's</returns>
|
||||
public IDataType[] GetAll()
|
||||
{
|
||||
var retVal = new IDataType[_controls.Count];
|
||||
var c = 0;
|
||||
|
||||
foreach (var id in _controls.Keys)
|
||||
{
|
||||
retVal[c] = GetNewObject(id);
|
||||
c++;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
return DataTypesResolver.Current.DataTypes.ToArray();
|
||||
}
|
||||
|
||||
private static void Initialize()
|
||||
{
|
||||
// Get all datatypes from interface
|
||||
var types = PluginTypeResolver.Current.ResolveDataTypes().ToArray();
|
||||
foreach (var t in types)
|
||||
{
|
||||
var instance = PluginTypeResolver.Current.CreateInstance<IDataType>(t);
|
||||
if (instance != null)
|
||||
{
|
||||
_controls.TryAdd(instance.Id, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user