using System; using System.Reflection; using System.Runtime.Serialization; using Umbraco.Core.Models.Entities; using Umbraco.Core.PropertyEditors; namespace Umbraco.Core.Models { /// /// Represents a Macro Property /// [Serializable] [DataContract(IsReference = true)] public class MacroProperty : BeingDirtyBase, IMacroProperty, IRememberBeingDirty, IDeepCloneable { public MacroProperty() { _key = Guid.NewGuid(); } /// /// Ctor for creating a new property /// /// /// /// /// public MacroProperty(string @alias, string name, int sortOrder, string editorAlias) { _alias = alias; _name = name; _sortOrder = sortOrder; _key = Guid.NewGuid(); _editorAlias = editorAlias; } /// /// Ctor for creating an existing property /// /// /// /// /// /// /// internal MacroProperty(int id, Guid key, string @alias, string name, int sortOrder, string editorAlias) { _id = id; _alias = alias; _name = name; _sortOrder = sortOrder; _key = key; _editorAlias = editorAlias; } private Guid _key; private string _alias; private string _name; private int _sortOrder; private int _id; private string _editorAlias; private static readonly Lazy Ps = new Lazy(); private class PropertySelectors { public readonly PropertyInfo KeySelector = ExpressionHelper.GetPropertyInfo(x => x.Key); public readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo(x => x.Alias); public readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo(x => x.Name); public readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo(x => x.SortOrder); public readonly PropertyInfo IdSelector = ExpressionHelper.GetPropertyInfo(x => x.Id); public readonly PropertyInfo PropertyTypeSelector = ExpressionHelper.GetPropertyInfo(x => x.EditorAlias); } /// /// Gets or sets the Key of the Property /// [DataMember] public Guid Key { get { return _key; } set { SetPropertyValueAndDetectChanges(value, ref _key, Ps.Value.KeySelector); } } /// /// Gets or sets the Alias of the Property /// [DataMember] public int Id { get { return _id; } set { SetPropertyValueAndDetectChanges(value, ref _id, Ps.Value.IdSelector); } } /// /// Gets or sets the Alias of the Property /// [DataMember] public string Alias { get { return _alias; } set { SetPropertyValueAndDetectChanges(value, ref _alias, Ps.Value.AliasSelector); } } /// /// Gets or sets the Name of the Property /// [DataMember] public string Name { get { return _name; } set { SetPropertyValueAndDetectChanges(value, ref _name, Ps.Value.NameSelector); } } /// /// Gets or sets the Sort Order of the Property /// [DataMember] public int SortOrder { get { return _sortOrder; } set { SetPropertyValueAndDetectChanges(value, ref _sortOrder, Ps.Value.SortOrderSelector); } } /// /// Gets or sets the Type for this Property /// /// /// The MacroPropertyTypes acts as a plugin for Macros. /// All types was previously contained in the database, but has been ported to code. /// [DataMember] public string EditorAlias { get { return _editorAlias; } set { SetPropertyValueAndDetectChanges(value, ref _editorAlias, Ps.Value.PropertyTypeSelector); } } public object DeepClone() { //Memberwise clone on MacroProperty will work since it doesn't have any deep elements // for any sub class this will work for standard properties as well that aren't complex object's themselves. var clone = (MacroProperty)MemberwiseClone(); //Automatically deep clone ref properties that are IDeepCloneable DeepCloneHelper.DeepCloneRefProperties(this, clone); clone.ResetDirtyProperties(false); return clone; } protected bool Equals(MacroProperty other) { return string.Equals(_alias, other._alias) && _id == other._id; } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; return Equals((MacroProperty) obj); } public override int GetHashCode() { unchecked { return ((_alias != null ? _alias.GetHashCode() : 0)*397) ^ _id; } } } }