From 81750c41bd50197fb8556af34212ae3f9cd4ffa1 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 25 Nov 2016 10:35:36 +0100 Subject: [PATCH] Removes events for filtering and instead use a special interface to perform the filtering, updates ctor for WeightAttribute to only accept positive numbers for public, internally it could be negative numbers, updates the filtering to always ensure that core handlers are at the beginning --- .../ApplicationEventsEventArgs.cs | 15 - .../ApplicationEventsResolver.cs | 53 +- .../IApplicationEventsFilter.cs | 12 + .../ManyObjectsResolverBase.cs | 631 +++++++++--------- .../ObjectResolution/WeightAttribute.cs | 19 +- src/Umbraco.Core/Umbraco.Core.csproj | 2 +- 6 files changed, 384 insertions(+), 348 deletions(-) delete mode 100644 src/Umbraco.Core/ObjectResolution/ApplicationEventsEventArgs.cs create mode 100644 src/Umbraco.Core/ObjectResolution/IApplicationEventsFilter.cs diff --git a/src/Umbraco.Core/ObjectResolution/ApplicationEventsEventArgs.cs b/src/Umbraco.Core/ObjectResolution/ApplicationEventsEventArgs.cs deleted file mode 100644 index a459fc7268..0000000000 --- a/src/Umbraco.Core/ObjectResolution/ApplicationEventsEventArgs.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Umbraco.Core.ObjectResolution -{ - public class ApplicationEventsEventArgs : EventArgs - { - public List Handlers { get; private set; } - - public ApplicationEventsEventArgs(List handlers) - { - Handlers = handlers; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs b/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs index 6933279258..53e8049ee9 100644 --- a/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs +++ b/src/Umbraco.Core/ObjectResolution/ApplicationEventsResolver.cs @@ -7,7 +7,7 @@ using umbraco.interfaces; namespace Umbraco.Core.ObjectResolution { - /// + /// /// A resolver to return all IApplicationEvents objects /// /// @@ -52,21 +52,47 @@ namespace Umbraco.Core.ObjectResolution { if (_orderedAndFiltered == null) { - _orderedAndFiltered = GetSortedValues().ToList(); - - //raise event so the collection can be modified - OnCollectionResolved(new ApplicationEventsEventArgs(_orderedAndFiltered)); + _orderedAndFiltered = GetSortedValues().ToList(); + OnCollectionResolved(_orderedAndFiltered); } return _orderedAndFiltered; } } - - public event EventHandler CollectionResolved; - - private void OnCollectionResolved(ApplicationEventsEventArgs e) + + /// + /// Allow any filters to be applied to the event handler list + /// + /// + /// + /// This allows custom logic to execute in order to filter or re-order the event handlers prior to executing, + /// however this also ensures that any core handlers are executed first to ensure the stabiliy of Umbraco. + /// + private void OnCollectionResolved(List handlers) { - var handler = CollectionResolved; - if (handler != null) handler(this, e); + foreach (var filter in handlers.OfType().ToArray()) + { + filter.Filter(handlers); + } + + //find all of the core handlers and their weight, remove them from the main list + var coreItems = new List>(); + foreach (var handler in handlers.ToArray()) + { + //Yuck, but not sure what else we can do + if ( + handler.GetType().Assembly.FullName.StartsWith("Umbraco.", StringComparison.OrdinalIgnoreCase) + || handler.GetType().Assembly.FullName.StartsWith("Concorde.")) + { + coreItems.Add(new Tuple(handler, GetObjectWeight(handler))); + handlers.Remove(handler); + } + } + + //re-add the core handlers to the beginning of the list ordered by their weight + foreach (var coreHandler in coreItems.OrderBy(x => x.Item2)) + { + handlers.Insert(0, coreHandler.Item1); + } } /// @@ -166,10 +192,7 @@ namespace Umbraco.Core.ObjectResolution _legacyResolver.Dispose(); ResetCollections(); _orderedAndFiltered.Clear(); - _orderedAndFiltered = null; - - //Clear event handlers - CollectionResolved = null; + _orderedAndFiltered = null; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/ObjectResolution/IApplicationEventsFilter.cs b/src/Umbraco.Core/ObjectResolution/IApplicationEventsFilter.cs new file mode 100644 index 0000000000..e295e791d8 --- /dev/null +++ b/src/Umbraco.Core/ObjectResolution/IApplicationEventsFilter.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace Umbraco.Core.ObjectResolution +{ + /// + /// This can be used to filter or re-order application events before they are executed + /// + public interface IApplicationEventsFilter + { + void Filter(List eventHandlers); + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs b/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs index 3519bf86bc..5e170f47f4 100644 --- a/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs +++ b/src/Umbraco.Core/ObjectResolution/ManyObjectsResolverBase.cs @@ -14,18 +14,18 @@ namespace Umbraco.Core.ObjectResolution /// The type of the concrete resolver class. /// The type of the resolved objects. public abstract class ManyObjectsResolverBase : ResolverBase - where TResolved : class + where TResolved : class where TResolver : ResolverBase - { - private Lazy> _applicationInstances; - private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); - private readonly string _httpContextKey; - private readonly List _instanceTypes = new List(); - private IEnumerable _sortedValues; + { + private Lazy> _applicationInstances; + private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); + private readonly string _httpContextKey; + private readonly List _instanceTypes = new List(); + private IEnumerable _sortedValues; - private int _defaultPluginWeight = 100; + private int _defaultPluginWeight = 100; - #region Constructors + #region Constructors /// /// Initializes a new instance of the class with an empty list of objects, @@ -61,11 +61,11 @@ namespace Umbraco.Core.ObjectResolution [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use ctor specifying IServiceProvider instead")] - protected ManyObjectsResolverBase(ObjectLifetimeScope scope = ObjectLifetimeScope.Application) + protected ManyObjectsResolverBase(ObjectLifetimeScope scope = ObjectLifetimeScope.Application) : this(new ActivatorServiceProvider(), LoggerResolver.Current.Logger, scope) - { - - } + { + + } /// /// Initializes a new instance of the class with an empty list of objects, @@ -76,19 +76,19 @@ namespace Umbraco.Core.ObjectResolution /// The HttpContextBase corresponding to the HttpRequest. /// is null. protected ManyObjectsResolverBase(IServiceProvider serviceProvider, ILogger logger, HttpContextBase httpContext) - { + { if (serviceProvider == null) throw new ArgumentNullException("serviceProvider"); if (httpContext == null) throw new ArgumentNullException("httpContext"); CanResolveBeforeFrozen = false; Logger = logger; - LifetimeScope = ObjectLifetimeScope.HttpRequest; - _httpContextKey = GetType().FullName; + LifetimeScope = ObjectLifetimeScope.HttpRequest; + _httpContextKey = GetType().FullName; ServiceProvider = serviceProvider; CurrentHttpContext = httpContext; - _instanceTypes = new List(); + _instanceTypes = new List(); InitializeAppInstances(); - } + } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use ctor specifying IServiceProvider instead")] @@ -110,57 +110,57 @@ namespace Umbraco.Core.ObjectResolution /// is per HttpRequest but the current HttpContext is null. protected ManyObjectsResolverBase(IServiceProvider serviceProvider, ILogger logger, IEnumerable value, ObjectLifetimeScope scope = ObjectLifetimeScope.Application) : this(serviceProvider, logger, scope) - { - _instanceTypes = value.ToList(); - } + { + _instanceTypes = value.ToList(); + } [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use ctor specifying IServiceProvider instead")] protected ManyObjectsResolverBase(IEnumerable value, ObjectLifetimeScope scope = ObjectLifetimeScope.Application) : this(new ActivatorServiceProvider(), LoggerResolver.Current.Logger, value, scope) { - + } - /// - /// Initializes a new instance of the class with an initial list of objects, - /// with creation of objects based on an HttpRequest lifetime scope. - /// - /// The HttpContextBase corresponding to the HttpRequest. - /// The list of object types. - /// is null. + /// + /// Initializes a new instance of the class with an initial list of objects, + /// with creation of objects based on an HttpRequest lifetime scope. + /// + /// The HttpContextBase corresponding to the HttpRequest. + /// The list of object types. + /// is null. [Obsolete("Use ctor specifying IServiceProvider instead")] protected ManyObjectsResolverBase(HttpContextBase httpContext, IEnumerable value) : this(new ActivatorServiceProvider(), LoggerResolver.Current.Logger, httpContext) - { - _instanceTypes = value.ToList(); - } - #endregion + { + _instanceTypes = value.ToList(); + } + #endregion private void InitializeAppInstances() { _applicationInstances = new Lazy>(() => CreateInstances().ToArray()); } - /// - /// Gets or sets a value indicating whether the resolver can resolve objects before resolution is frozen. - /// - /// This is false by default and is used for some special internal resolvers. - internal bool CanResolveBeforeFrozen { get; set; } + /// + /// Gets or sets a value indicating whether the resolver can resolve objects before resolution is frozen. + /// + /// This is false by default and is used for some special internal resolvers. + internal bool CanResolveBeforeFrozen { get; set; } - /// - /// Gets the list of types to create instances from. - /// - protected virtual IEnumerable InstanceTypes - { - get { return _instanceTypes; } - } + /// + /// Gets the list of types to create instances from. + /// + protected virtual IEnumerable InstanceTypes + { + get { return _instanceTypes; } + } - /// - /// Gets or sets the used to initialize this object, if any. - /// - /// If not null, then LifetimeScope will be ObjectLifetimeScope.HttpRequest. - protected HttpContextBase CurrentHttpContext { get; private set; } + /// + /// Gets or sets the used to initialize this object, if any. + /// + /// If not null, then LifetimeScope will be ObjectLifetimeScope.HttpRequest. + protected HttpContextBase CurrentHttpContext { get; private set; } /// /// Returns the service provider used to instantiate objects @@ -174,16 +174,16 @@ namespace Umbraco.Core.ObjectResolution /// protected ObjectLifetimeScope LifetimeScope { get; private set; } - /// - /// Gets the resolved object instances, sorted by weight. - /// - /// The sorted resolved object instances. - /// - /// The order is based upon the WeightAttribute and DefaultPluginWeight. - /// Weights are sorted ascendingly (lowest weights come first). - /// - protected IEnumerable GetSortedValues() - { + /// + /// Gets the resolved object instances, sorted by weight. + /// + /// The sorted resolved object instances. + /// + /// The order is based upon the WeightAttribute and DefaultPluginWeight. + /// Weights are sorted ascendingly (lowest weights come first). + /// + protected IEnumerable GetSortedValues() + { if (_sortedValues == null) { var values = Values.ToList(); @@ -191,18 +191,18 @@ namespace Umbraco.Core.ObjectResolution _sortedValues = values; } return _sortedValues; - } + } - /// - /// Gets or sets the default type weight. - /// - /// Determines the weight of types that do not have a WeightAttribute set on - /// them, when calling GetSortedValues. - protected virtual int DefaultPluginWeight - { - get { return _defaultPluginWeight; } - set { _defaultPluginWeight = value; } - } + /// + /// Gets or sets the default type weight. + /// + /// Determines the weight of types that do not have a WeightAttribute set on + /// them, when calling GetSortedValues. + protected virtual int DefaultPluginWeight + { + get { return _defaultPluginWeight; } + set { _defaultPluginWeight = value; } + } /// /// Returns the weight of an object for user with GetSortedValues @@ -210,22 +210,22 @@ namespace Umbraco.Core.ObjectResolution /// /// protected virtual int GetObjectWeight(object o) - { - var type = o.GetType(); - var attr = type.GetCustomAttribute(true); - return attr == null ? DefaultPluginWeight : attr.Weight; - } + { + var type = o.GetType(); + var attr = type.GetCustomAttribute(true); + return attr == null ? DefaultPluginWeight : attr.Weight; + } - /// - /// Gets the resolved object instances. - /// - /// CanResolveBeforeFrozen is false, and resolution is not frozen. - protected IEnumerable Values - { - get - { - using (Resolution.Reader(CanResolveBeforeFrozen)) - { + /// + /// Gets the resolved object instances. + /// + /// CanResolveBeforeFrozen is false, and resolution is not frozen. + protected IEnumerable Values + { + get + { + using (Resolution.Reader(CanResolveBeforeFrozen)) + { // note: we apply .ToArray() to the output of CreateInstance() because that is an IEnumerable that // comes from the PluginManager we want to be _sure_ that it's not a Linq of some sort, but the // instances have actually been instanciated when we return. @@ -247,7 +247,7 @@ namespace Umbraco.Core.ObjectResolution CurrentHttpContext.Items[_httpContextKey] = instances; } return (TResolved[])CurrentHttpContext.Items[_httpContextKey]; - + case ObjectLifetimeScope.Application: return _applicationInstances.Value; @@ -258,132 +258,132 @@ namespace Umbraco.Core.ObjectResolution return CreateInstances().ToArray(); } } - } - } + } + } - /// - /// Creates the object instances for the types contained in the types collection. - /// - /// A list of objects of type . - protected virtual IEnumerable CreateInstances() - { - return ServiceProvider.CreateInstances(InstanceTypes, Logger); - } + /// + /// Creates the object instances for the types contained in the types collection. + /// + /// A list of objects of type . + protected virtual IEnumerable CreateInstances() + { + return ServiceProvider.CreateInstances(InstanceTypes, Logger); + } - #region Types collection manipulation + #region Types collection manipulation - /// - /// Removes a type. - /// - /// The type to remove. - /// the resolver does not support removing types, or - /// the type is not a valid type for the resolver. - public virtual void RemoveType(Type value) - { - EnsureSupportsRemove(); + /// + /// Removes a type. + /// + /// The type to remove. + /// the resolver does not support removing types, or + /// the type is not a valid type for the resolver. + public virtual void RemoveType(Type value) + { + EnsureSupportsRemove(); - using (Resolution.Configuration) - using (var l = new UpgradeableReadLock(_lock)) - { - EnsureCorrectType(value); + using (Resolution.Configuration) + using (var l = new UpgradeableReadLock(_lock)) + { + EnsureCorrectType(value); - l.UpgradeToWriteLock(); - _instanceTypes.Remove(value); - } - } + l.UpgradeToWriteLock(); + _instanceTypes.Remove(value); + } + } - /// - /// Removes a type. - /// - /// The type to remove. - /// the resolver does not support removing types, or - /// the type is not a valid type for the resolver. - public void RemoveType() + /// + /// Removes a type. + /// + /// The type to remove. + /// the resolver does not support removing types, or + /// the type is not a valid type for the resolver. + public void RemoveType() where T : TResolved - { - RemoveType(typeof(T)); - } + { + RemoveType(typeof(T)); + } - /// - /// Adds types. - /// - /// The types to add. - /// The types are appended at the end of the list. - /// the resolver does not support adding types, or - /// a type is not a valid type for the resolver, or a type is already in the collection of types. - protected void AddTypes(IEnumerable types) - { - EnsureSupportsAdd(); + /// + /// Adds types. + /// + /// The types to add. + /// The types are appended at the end of the list. + /// the resolver does not support adding types, or + /// a type is not a valid type for the resolver, or a type is already in the collection of types. + protected void AddTypes(IEnumerable types) + { + EnsureSupportsAdd(); - using (Resolution.Configuration) - using (new WriteLock(_lock)) - { - foreach(var t in types) - { - EnsureCorrectType(t); + using (Resolution.Configuration) + using (new WriteLock(_lock)) + { + foreach (var t in types) + { + EnsureCorrectType(t); if (_instanceTypes.Contains(t)) - { - throw new InvalidOperationException(string.Format( - "Type {0} is already in the collection of types.", t.FullName)); - } - _instanceTypes.Add(t); - } - } - } + { + throw new InvalidOperationException(string.Format( + "Type {0} is already in the collection of types.", t.FullName)); + } + _instanceTypes.Add(t); + } + } + } - /// - /// Adds a type. - /// - /// The type to add. - /// The type is appended at the end of the list. - /// the resolver does not support adding types, or - /// the type is not a valid type for the resolver, or the type is already in the collection of types. - public virtual void AddType(Type value) - { - EnsureSupportsAdd(); + /// + /// Adds a type. + /// + /// The type to add. + /// The type is appended at the end of the list. + /// the resolver does not support adding types, or + /// the type is not a valid type for the resolver, or the type is already in the collection of types. + public virtual void AddType(Type value) + { + EnsureSupportsAdd(); - using (Resolution.Configuration) - using (var l = new UpgradeableReadLock(_lock)) - { - EnsureCorrectType(value); + using (Resolution.Configuration) + using (var l = new UpgradeableReadLock(_lock)) + { + EnsureCorrectType(value); if (_instanceTypes.Contains(value)) - { - throw new InvalidOperationException(string.Format( - "Type {0} is already in the collection of types.", value.FullName)); - } + { + throw new InvalidOperationException(string.Format( + "Type {0} is already in the collection of types.", value.FullName)); + } - l.UpgradeToWriteLock(); - _instanceTypes.Add(value); - } - } + l.UpgradeToWriteLock(); + _instanceTypes.Add(value); + } + } - /// - /// Adds a type. - /// - /// The type to add. - /// The type is appended at the end of the list. - /// the resolver does not support adding types, or - /// the type is not a valid type for the resolver, or the type is already in the collection of types. - public void AddType() + /// + /// Adds a type. + /// + /// The type to add. + /// The type is appended at the end of the list. + /// the resolver does not support adding types, or + /// the type is not a valid type for the resolver, or the type is already in the collection of types. + public void AddType() where T : TResolved - { - AddType(typeof(T)); - } + { + AddType(typeof(T)); + } - /// - /// Clears the list of types - /// - /// the resolver does not support clearing types. - public virtual void Clear() - { - EnsureSupportsClear(); + /// + /// Clears the list of types + /// + /// the resolver does not support clearing types. + public virtual void Clear() + { + EnsureSupportsClear(); - using (Resolution.Configuration) - using (new WriteLock(_lock)) - { - _instanceTypes.Clear(); - } - } + using (Resolution.Configuration) + using (new WriteLock(_lock)) + { + _instanceTypes.Clear(); + } + } /// /// WARNING! Do not use this unless you know what you are doing, clear all types registered and instances @@ -399,32 +399,32 @@ namespace Umbraco.Core.ObjectResolution } } - /// - /// Inserts a type at the specified index. - /// - /// The zero-based index at which the type should be inserted. - /// The type to insert. - /// the resolver does not support inserting types, or - /// the type is not a valid type for the resolver, or the type is already in the collection of types. - /// is out of range. - public virtual void InsertType(int index, Type value) - { - EnsureSupportsInsert(); + /// + /// Inserts a type at the specified index. + /// + /// The zero-based index at which the type should be inserted. + /// The type to insert. + /// the resolver does not support inserting types, or + /// the type is not a valid type for the resolver, or the type is already in the collection of types. + /// is out of range. + public virtual void InsertType(int index, Type value) + { + EnsureSupportsInsert(); - using (Resolution.Configuration) - using (var l = new UpgradeableReadLock(_lock)) - { - EnsureCorrectType(value); + using (Resolution.Configuration) + using (var l = new UpgradeableReadLock(_lock)) + { + EnsureCorrectType(value); if (_instanceTypes.Contains(value)) - { - throw new InvalidOperationException(string.Format( - "Type {0} is already in the collection of types.", value.FullName)); - } + { + throw new InvalidOperationException(string.Format( + "Type {0} is already in the collection of types.", value.FullName)); + } - l.UpgradeToWriteLock(); - _instanceTypes.Insert(index, value); - } - } + l.UpgradeToWriteLock(); + _instanceTypes.Insert(index, value); + } + } /// /// Inserts a type at the beginning of the list. @@ -445,9 +445,9 @@ namespace Umbraco.Core.ObjectResolution /// is out of range. public void InsertType(int index) where T : TResolved - { - InsertType(index, typeof(T)); - } + { + InsertType(index, typeof(T)); + } /// /// Inserts a type at the beginning of the list. @@ -458,68 +458,68 @@ namespace Umbraco.Core.ObjectResolution { InsertType(0, typeof(T)); } - - /// - /// Inserts a type before a specified, already existing type. - /// - /// The existing type before which to insert. - /// The type to insert. - /// the resolver does not support inserting types, or - /// one of the types is not a valid type for the resolver, or the existing type is not in the collection, - /// or the new type is already in the collection of types. - public virtual void InsertTypeBefore(Type existingType, Type value) - { - EnsureSupportsInsert(); - using (Resolution.Configuration) - using (var l = new UpgradeableReadLock(_lock)) - { - EnsureCorrectType(existingType); - EnsureCorrectType(value); + /// + /// Inserts a type before a specified, already existing type. + /// + /// The existing type before which to insert. + /// The type to insert. + /// the resolver does not support inserting types, or + /// one of the types is not a valid type for the resolver, or the existing type is not in the collection, + /// or the new type is already in the collection of types. + public virtual void InsertTypeBefore(Type existingType, Type value) + { + EnsureSupportsInsert(); + + using (Resolution.Configuration) + using (var l = new UpgradeableReadLock(_lock)) + { + EnsureCorrectType(existingType); + EnsureCorrectType(value); if (_instanceTypes.Contains(existingType) == false) - { - throw new InvalidOperationException(string.Format( - "Type {0} is not in the collection of types.", existingType.FullName)); - } + { + throw new InvalidOperationException(string.Format( + "Type {0} is not in the collection of types.", existingType.FullName)); + } if (_instanceTypes.Contains(value)) - { - throw new InvalidOperationException(string.Format( - "Type {0} is already in the collection of types.", value.FullName)); - } + { + throw new InvalidOperationException(string.Format( + "Type {0} is already in the collection of types.", value.FullName)); + } int index = _instanceTypes.IndexOf(existingType); - l.UpgradeToWriteLock(); - _instanceTypes.Insert(index, value); - } - } + l.UpgradeToWriteLock(); + _instanceTypes.Insert(index, value); + } + } - /// - /// Inserts a type before a specified, already existing type. - /// - /// The existing type before which to insert. - /// The type to insert. - /// the resolver does not support inserting types, or - /// one of the types is not a valid type for the resolver, or the existing type is not in the collection, - /// or the new type is already in the collection of types. - public void InsertTypeBefore() + /// + /// Inserts a type before a specified, already existing type. + /// + /// The existing type before which to insert. + /// The type to insert. + /// the resolver does not support inserting types, or + /// one of the types is not a valid type for the resolver, or the existing type is not in the collection, + /// or the new type is already in the collection of types. + public void InsertTypeBefore() where TExisting : TResolved where T : TResolved - { - InsertTypeBefore(typeof(TExisting), typeof(T)); - } + { + InsertTypeBefore(typeof(TExisting), typeof(T)); + } - /// - /// Returns a value indicating whether the specified type is already in the collection of types. - /// - /// The type to look for. - /// A value indicating whether the type is already in the collection of types. - public virtual bool ContainsType(Type value) - { - using (new ReadLock(_lock)) - { - return _instanceTypes.Contains(value); - } - } + /// + /// Returns a value indicating whether the specified type is already in the collection of types. + /// + /// The type to look for. + /// A value indicating whether the type is already in the collection of types. + public virtual bool ContainsType(Type value) + { + using (new ReadLock(_lock)) + { + return _instanceTypes.Contains(value); + } + } /// /// Gets the types in the collection of types. @@ -536,27 +536,27 @@ namespace Umbraco.Core.ObjectResolution return types; } - /// - /// Returns a value indicating whether the specified type is already in the collection of types. - /// - /// The type to look for. - /// A value indicating whether the type is already in the collection of types. - public bool ContainsType() + /// + /// Returns a value indicating whether the specified type is already in the collection of types. + /// + /// The type to look for. + /// A value indicating whether the type is already in the collection of types. + public bool ContainsType() where T : TResolved - { - return ContainsType(typeof(T)); - } + { + return ContainsType(typeof(T)); + } - #endregion + #endregion - /// - /// Returns a WriteLock to use when modifying collections - /// - /// - protected WriteLock GetWriteLock() - { - return new WriteLock(_lock); - } + /// + /// Returns a WriteLock to use when modifying collections + /// + /// + protected WriteLock GetWriteLock() + { + return new WriteLock(_lock); + } #region Type utilities @@ -581,70 +581,71 @@ namespace Umbraco.Core.ObjectResolution /// /// The resolver does not support removing types. protected void EnsureSupportsRemove() - { - if (SupportsRemove == false) + { + if (SupportsRemove == false) throw new InvalidOperationException("This resolver does not support removing types"); - } + } /// /// Ensures that the resolver supports clearing types. /// /// The resolver does not support clearing types. - protected void EnsureSupportsClear() { - if (SupportsClear == false) + protected void EnsureSupportsClear() + { + if (SupportsClear == false) throw new InvalidOperationException("This resolver does not support clearing types"); - } + } /// /// Ensures that the resolver supports adding types. /// /// The resolver does not support adding types. protected void EnsureSupportsAdd() - { - if (SupportsAdd == false) + { + if (SupportsAdd == false) throw new InvalidOperationException("This resolver does not support adding new types"); - } + } /// /// Ensures that the resolver supports inserting types. /// /// The resolver does not support inserting types. protected void EnsureSupportsInsert() - { - if (SupportsInsert == false) + { + if (SupportsInsert == false) throw new InvalidOperationException("This resolver does not support inserting new types"); - } + } /// /// Gets a value indicating whether the resolver supports adding types. /// protected virtual bool SupportsAdd - { - get { return true; } - } + { + get { return true; } + } /// /// Gets a value indicating whether the resolver supports inserting types. /// protected virtual bool SupportsInsert - { - get { return true; } - } + { + get { return true; } + } /// /// Gets a value indicating whether the resolver supports clearing types. /// protected virtual bool SupportsClear - { - get { return true; } - } + { + get { return true; } + } /// /// Gets a value indicating whether the resolver supports removing types. /// protected virtual bool SupportsRemove - { - get { return true; } + { + get { return true; } } #endregion diff --git a/src/Umbraco.Core/ObjectResolution/WeightAttribute.cs b/src/Umbraco.Core/ObjectResolution/WeightAttribute.cs index f360443c55..35f10a4111 100644 --- a/src/Umbraco.Core/ObjectResolution/WeightAttribute.cs +++ b/src/Umbraco.Core/ObjectResolution/WeightAttribute.cs @@ -8,13 +8,28 @@ namespace Umbraco.Core.ObjectResolution [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public class WeightAttribute : Attribute { + /// + /// Initializes a new instance of the class with a weight. + /// + /// The object type weight. + /// + /// This internal constructor allows for internal Umbraco products to set a negative number weight + /// + internal WeightAttribute(int weight) + { + Weight = weight; + } + /// /// Initializes a new instance of the class with a weight. /// /// The object type weight. - public WeightAttribute(int weight) + /// + /// The weight must be a positive number + /// + public WeightAttribute(uint weight) { - Weight = weight; + Weight = Convert.ToInt32(weight); } /// diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index dbd5199009..2619a1c80c 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -415,7 +415,7 @@ - +