public void RegisterProperty(Type targetType, ItemProperty property) { if (!typeof(IExtendedDataItem).IsAssignableFrom (targetType)) throw new InvalidOperationException ("The type '" + targetType + "' does not implement the IExtendedDataItem interface and cannot be extended with new properties"); ClassDataType ctype = (ClassDataType) GetConfigurationDataType (targetType); ctype.AddProperty (property); }
public void AddProperty(ItemProperty prop) { if (!prop.IsNested) { foreach (ItemProperty p in sortedPoperties) { if (p.IsNested && p.NameList[0] == prop.Name) throw CreateNestedConflictException (prop, p); } } else { ItemProperty p = properties [prop.NameList[0]] as ItemProperty; if (p != null) throw CreateNestedConflictException (prop, p); } prop.SetContext (Context); if (properties.ContainsKey (prop.Name)) throw new InvalidOperationException ("Duplicate property '" + prop.Name + "' in class '" + ValueType); properties.Add (prop.Name, prop); sortedPoperties.Add (prop); if (subtypes != null && subtypes.Count > 0) { foreach (ClassDataType subtype in subtypes) subtype.AddProperty (prop); } }
void SetPropValue(ItemProperty prop, object obj, object value) { if (prop.Member != null) prop.SetValue (obj, value); else if (obj is IExtendedDataItem) ((IExtendedDataItem)obj).ExtendedProperties [prop.Name] = value; }
object GetPropValue(ItemProperty prop, object obj) { if (prop.Member != null) return prop.GetValue (obj); else if (obj is IExtendedDataItem) return ((IExtendedDataItem)obj).ExtendedProperties [prop.Name]; else return null; }
Exception CreateNestedConflictException(ItemProperty p1, ItemProperty p2) { return new InvalidOperationException ("There is a conflict between the properties '" + p1.Name + "' and '" + p2.Name + "'. Nested element properties can't be mixed with normal element properties."); }
protected override void Initialize() { object[] incs = ValueType.GetCustomAttributes (typeof (DataIncludeAttribute), true); foreach (DataIncludeAttribute incat in incs) { Context.IncludeType (incat.Type); } if (ValueType.BaseType != null) { ClassDataType baseType = (ClassDataType) Context.GetConfigurationDataType (ValueType.BaseType); baseType.AddSubtype (this); int n=0; foreach (ItemProperty prop in baseType.Properties) { properties.Add (prop.Name, prop); sortedPoperties.Insert (n++, prop); } } foreach (Type interf in ValueType.GetInterfaces ()) { ClassDataType baseType = (ClassDataType) Context.GetConfigurationDataType (interf); baseType.AddSubtype (this); } MemberInfo[] members = ValueType.GetMembers (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (MemberInfo member in members) { if ((member is FieldInfo || member is PropertyInfo) && member.DeclaringType == ValueType) { object[] ats = member.GetCustomAttributes (true); ItemPropertyAttribute at = FindPropertyAttribute (ats, 0); if (at == null) continue; ItemProperty prop = new ItemProperty (); prop.Name = (at.Name != null) ? at.Name : member.Name; prop.ExpandedCollection = member.IsDefined (typeof(ExpandedCollectionAttribute), true); prop.DefaultValue = at.DefaultValue; Type memberType = member is FieldInfo ? ((FieldInfo)member).FieldType : ((PropertyInfo)member).PropertyType; if (prop.ExpandedCollection) { ICollectionHandler handler = Context.GetCollectionHandler (memberType); if (handler == null) throw new InvalidOperationException ("ExpandedCollectionAttribute can't be applied to property '" + prop.Name + "' in type '" + ValueType + "' becuase it is not a valid collection."); memberType = handler.GetItemType (); prop.ExpandedCollectionHandler = handler; } if (at.ValueType != null) prop.PropertyType = at.ValueType; else prop.PropertyType = memberType; if (at.SerializationDataType != null) { try { prop.DataType = (DataType) Activator.CreateInstance (at.SerializationDataType, new object[] { prop.PropertyType } ); } catch (MissingMethodException ex) { throw new InvalidOperationException ("Constructor not found for custom data type: " + at.SerializationDataType.Name + " (Type propertyType);", ex); } } prop.Member = member; AddProperty (prop); prop.Initialize (ats, 0); if (prop.ExpandedCollection && prop.DataType.IsSimpleType) throw new InvalidOperationException ("ExpandedCollectionAttribute is not allowed in collections of simple types"); } } }