public ParentSchema(TypeSchema schema, PropertyInfo propInfo, ParentAttribute parentData) { Trace.WriteLineIf(DebugOutput.Enabled, String.Format(CultureInfo.CurrentCulture, "Creating ParentSchema for property {0} and column {1}", propInfo.Name, parentData.ColumnName)); this.schema = schema; this.propInfo = propInfo; this.parentData = parentData; }
/// <summary> /// Set the metadata of parent. /// </summary> /// <param name="parent">Parent attribute.</param> protected virtual void SetParent(ParentAttribute parent) { if (parent == null) { throw new ArgumentNullException("display"); } ParentProperty = GetProperty(parent.PropertyName); }
public static void DefaultEquality() { var a1 = new ParentAttribute { Prop = 1 }; var a2 = new ParentAttribute { Prop = 42 }; var a3 = new ParentAttribute { Prop = 1 }; var d1 = new ChildAttribute { Prop = 1 }; var d2 = new ChildAttribute { Prop = 42 }; var d3 = new ChildAttribute { Prop = 1 }; var s1 = new GrandchildAttribute { Prop = 1 }; var s2 = new GrandchildAttribute { Prop = 42 }; var s3 = new GrandchildAttribute { Prop = 1 }; var f1 = new ChildAttributeWithField { Prop = 1 }; var f2 = new ChildAttributeWithField { Prop = 42 }; var f3 = new ChildAttributeWithField { Prop = 1 }; Assert.NotEqual(a1, a2); Assert.NotEqual(a2, a3); Assert.Equal(a1, a3); Assert.NotEqual(d1, d2); Assert.NotEqual(d2, d3); Assert.Equal(d1, d3); Assert.NotEqual(s1, s2); Assert.NotEqual(s2, s3); Assert.Equal(s1, s3); Assert.NotEqual(f1, f2); Assert.NotEqual(f2, f3); Assert.Equal(f1, f3); Assert.NotEqual(d1, a1); Assert.NotEqual(d2, a2); Assert.NotEqual(d3, a3); Assert.NotEqual(d1, a3); Assert.NotEqual(d3, a1); Assert.NotEqual(d1, s1); Assert.NotEqual(d2, s2); Assert.NotEqual(d3, s3); Assert.NotEqual(d1, s3); Assert.NotEqual(d3, s1); Assert.NotEqual(f1, a1); Assert.NotEqual(f2, a2); Assert.NotEqual(f3, a3); Assert.NotEqual(f1, a3); Assert.NotEqual(f3, a1); }
/// <summary> /// Set the metadata automatic. /// </summary> protected virtual void SetMetadata() { DisplayNameAttribute display = Type.GetCustomAttribute <DisplayNameAttribute>(); if (display != null) { SetDisplay(display); } else { Name = Type.Name; } DisplayColumnAttribute displayColumn = Type.GetCustomAttribute <DisplayColumnAttribute>(); if (displayColumn != null) { SetDisplayColumn(displayColumn); } else { DisplayProperty = GetProperty("Index"); } ParentAttribute parent = Type.GetCustomAttribute <ParentAttribute>(); if (parent != null) { SetParent(parent); } EntityAuthenticationAttribute authenticate = Type.GetCustomAttribute <EntityAuthenticationAttribute>(); if (authenticate == null) { AllowAnonymous = true; AddRoles = new string[0]; EditRoles = new string[0]; ViewRoles = new string[0]; RemoveRoles = new string[0]; } else { SetAuthentication(authenticate); } }
/// <summary> Write a Parent XML Element from attributes in a member. </summary> public virtual void WriteParent(System.Xml.XmlWriter writer, System.Reflection.MemberInfo member, ParentAttribute attribute, BaseAttribute parentAttribute, System.Type mappedClass) { writer.WriteStartElement( "parent" ); // Attribute: <name> writer.WriteAttributeString("name", attribute.Name==null ? DefaultHelper.Get_Parent_Name_DefaultValue(member) : GetAttributeValue(attribute.Name, mappedClass)); WriteUserDefinedContent(writer, member, null, attribute); writer.WriteEndElement(); }
public static void DefaultHashCode() { var a1 = new ParentAttribute { Prop = 1 }; var a2 = new ParentAttribute { Prop = 42 }; var a3 = new ParentAttribute { Prop = 1 }; var d1 = new ChildAttribute { Prop = 1 }; var d2 = new ChildAttribute { Prop = 42 }; var d3 = new ChildAttribute { Prop = 1 }; var s1 = new GrandchildAttribute { Prop = 1 }; var s2 = new GrandchildAttribute { Prop = 42 }; var s3 = new GrandchildAttribute { Prop = 1 }; var f1 = new ChildAttributeWithField { Prop = 1 }; var f2 = new ChildAttributeWithField { Prop = 42 }; var f3 = new ChildAttributeWithField { Prop = 1 }; Assert.NotEqual(a1.GetHashCode(), 0); Assert.NotEqual(a2.GetHashCode(), 0); Assert.NotEqual(a3.GetHashCode(), 0); Assert.NotEqual(d1.GetHashCode(), 0); Assert.NotEqual(d2.GetHashCode(), 0); Assert.NotEqual(d3.GetHashCode(), 0); Assert.NotEqual(s1.GetHashCode(), 0); Assert.NotEqual(s2.GetHashCode(), 0); Assert.NotEqual(s3.GetHashCode(), 0); Assert.Equal(f1.GetHashCode(), 0); Assert.Equal(f2.GetHashCode(), 0); Assert.Equal(f3.GetHashCode(), 0); Assert.NotEqual(a1.GetHashCode(), a2.GetHashCode()); Assert.NotEqual(a2.GetHashCode(), a3.GetHashCode()); Assert.Equal(a1.GetHashCode(), a3.GetHashCode()); Assert.NotEqual(s1.GetHashCode(), s2.GetHashCode()); Assert.NotEqual(s2.GetHashCode(), s3.GetHashCode()); Assert.Equal(s1.GetHashCode(), s3.GetHashCode()); Assert.NotEqual(d1.GetHashCode(), d2.GetHashCode()); Assert.NotEqual(d2.GetHashCode(), d3.GetHashCode()); Assert.Equal(d1.GetHashCode(), d3.GetHashCode()); Assert.Equal(f1.GetHashCode(), f2.GetHashCode()); Assert.Equal(f2.GetHashCode(), f3.GetHashCode()); Assert.Equal(f1.GetHashCode(), f3.GetHashCode()); Assert.Equal(d1.GetHashCode(), a1.GetHashCode()); Assert.Equal(d2.GetHashCode(), a2.GetHashCode()); Assert.Equal(d3.GetHashCode(), a3.GetHashCode()); Assert.Equal(d1.GetHashCode(), a3.GetHashCode()); Assert.Equal(d3.GetHashCode(), a1.GetHashCode()); Assert.Equal(d1.GetHashCode(), s1.GetHashCode()); Assert.Equal(d2.GetHashCode(), s2.GetHashCode()); Assert.Equal(d3.GetHashCode(), s3.GetHashCode()); Assert.Equal(d1.GetHashCode(), s3.GetHashCode()); Assert.Equal(d3.GetHashCode(), s1.GetHashCode()); Assert.NotEqual(f1.GetHashCode(), a1.GetHashCode()); Assert.NotEqual(f2.GetHashCode(), a2.GetHashCode()); Assert.NotEqual(f3.GetHashCode(), a3.GetHashCode()); Assert.NotEqual(f1.GetHashCode(), a3.GetHashCode()); Assert.NotEqual(f3.GetHashCode(), a1.GetHashCode()); }
private void Initialize(EntityEditorViewModel <TEntity> viewModel, EditorItemFactory factory) { if (viewModel == null) { throw new ArgumentNullException("viewModel"); } ViewModel = viewModel; Type type = typeof(TEntity); Grid grid = new Grid(); grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(100, GridUnitType.Star) }); grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(100, GridUnitType.Pixel) }); ParentAttribute parent = type.GetCustomAttributes(typeof(ParentAttribute), true).FirstOrDefault() as ParentAttribute; Grid dataGrid = new Grid(); dataGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(200, GridUnitType.Pixel) }); dataGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); Items = new List <EditorItem>(); foreach (var property in viewModel.ViewBuilder.EditableProperties) { dataGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto), MinHeight = 32 }); var name = new Label(); name.HorizontalAlignment = System.Windows.HorizontalAlignment.Right; name.VerticalAlignment = System.Windows.VerticalAlignment.Center; name.Margin = new Thickness(4); var display = type.GetProperty(property).GetCustomAttributes(typeof(DisplayAttribute), false).FirstOrDefault() as DisplayAttribute; if (display == null) { name.Content = property; } else { name.Content = display.Name; name.ToolTip = display.Description; } Grid.SetRow(name, dataGrid.RowDefinitions.Count - 1); dataGrid.Children.Add(name); EditorItem editor = factory.GetEditorItem(type.GetProperty(property)); editor.Title = (string)name.Content; editor.Tag = type.GetProperty(property); editor.Value = type.GetProperty(property).GetValue(viewModel.Item, null); Items.Add(editor); editor.Margin = new Thickness(4); editor.Initialized = true; Grid.SetRow(editor, dataGrid.RowDefinitions.Count - 1); Grid.SetColumn(editor, 1); dataGrid.Children.Add(editor); } ScrollViewer scroll = new ScrollViewer(); scroll.VerticalScrollBarVisibility = ScrollBarVisibility.Auto; scroll.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled; scroll.PanningMode = PanningMode.VerticalOnly; scroll.Content = dataGrid; grid.Children.Add(scroll); AppButtonPanel appButtonPanel = new AppButtonPanel(); Grid.SetRow(appButtonPanel, 1); grid.Children.Add(appButtonPanel); AppButton ok = new AppButton(new CustomCommand(null, Ok)); ok.Text = "确定"; ok.Image = (Canvas)Resources["appbar_check"]; appButtonPanel.Items.Add(ok); AppButton cancel = new AppButton(new CustomCommand(null, Cancel)); cancel.Text = "取消"; cancel.Image = (Canvas)Resources["appbar_close"]; appButtonPanel.Items.Add(cancel); Content = grid; }
/// <summary> /// Initialize entity metadata. /// </summary> /// <param name="type"></param> public EntityMetadata(Type type) { if (type == null) { throw new ArgumentNullException("type"); } Type = type; KeyType = type.GetProperty("Index").PropertyType; PropertyInfo[] properties = type.GetProperties().Where(t => t.GetGetMethod() != null && t.GetSetMethod() != null).ToArray(); Properties = properties.Select(t => new PropertyMetadata(t)).OrderBy(t => t.Order).ToArray(); ViewProperties = Properties.Where(t => !t.IsHiddenOnView).ToArray(); EditProperties = Properties.Where(t => !t.IsHiddenOnEdit).ToArray(); SearchProperties = Properties.Where(t => t.Searchable).ToArray(); DetailProperties = Properties.Where(t => !t.IsHiddenOnDetail).ToArray(); _Properties = new Dictionary <string, PropertyMetadata>(); for (int i = 0; i < Properties.Length; i++) { _Properties.Add(Properties[i].Property.Name, Properties[i]); } EntityAuthenticationAttribute authenticate = type.GetCustomAttribute <EntityAuthenticationAttribute>(); if (authenticate == null) { AllowAnonymous = true; AddRoles = new string[0]; EditRoles = new string[0]; ViewRoles = new string[0]; RemoveRoles = new string[0]; } else { AllowAnonymous = authenticate.AllowAnonymous; AddRoles = authenticate.AddRolesRequired; EditRoles = authenticate.EditRolesRequired; ViewRoles = authenticate.ViewRolesRequired; RemoveRoles = authenticate.RemoveRolesRequired; } DisplayNameAttribute display = type.GetCustomAttribute <DisplayNameAttribute>(); if (display != null) { Name = display.DisplayName == null ? type.Name : display.DisplayName; } else { Name = type.Name; } DisplayColumnAttribute displayColumn = type.GetCustomAttribute <DisplayColumnAttribute>(); if (displayColumn != null) { DisplayProperty = GetProperty(displayColumn.DisplayColumn); if (displayColumn.SortColumn != null) { SortProperty = Properties.SingleOrDefault(t => t.Property.Name == displayColumn.SortColumn); SortDescending = displayColumn.SortDescending; } } else { DisplayProperty = GetProperty("Index"); } ParentAttribute parent = type.GetCustomAttribute <ParentAttribute>(); if (parent != null) { ParentProperty = Properties.SingleOrDefault(t => t.Property.Name == parent.PropertyName); ParentLevel = parent.Level; } }
public static void DefaultHashCode() { var a1 = new ParentAttribute { Prop = 1 }; var a2 = new ParentAttribute { Prop = 42 }; var a3 = new ParentAttribute { Prop = 1 }; var d1 = new ChildAttribute { Prop = 1 }; var d2 = new ChildAttribute { Prop = 42 }; var d3 = new ChildAttribute { Prop = 1 }; var s1 = new GrandchildAttribute { Prop = 1 }; var s2 = new GrandchildAttribute { Prop = 42 }; var s3 = new GrandchildAttribute { Prop = 1 }; var f1 = new ChildAttributeWithField { Prop = 1 }; var f2 = new ChildAttributeWithField { Prop = 42 }; var f3 = new ChildAttributeWithField { Prop = 1 }; Assert.NotEqual(0, a1.GetHashCode()); Assert.NotEqual(0, a2.GetHashCode()); Assert.NotEqual(0, a3.GetHashCode()); Assert.NotEqual(0, d1.GetHashCode()); Assert.NotEqual(0, d2.GetHashCode()); Assert.NotEqual(0, d3.GetHashCode()); Assert.NotEqual(0, s1.GetHashCode()); Assert.NotEqual(0, s2.GetHashCode()); Assert.NotEqual(0, s3.GetHashCode()); Assert.Equal(0, f1.GetHashCode()); Assert.Equal(0, f2.GetHashCode()); Assert.Equal(0, f3.GetHashCode()); Assert.NotEqual(a1.GetHashCode(), a2.GetHashCode()); Assert.NotEqual(a2.GetHashCode(), a3.GetHashCode()); Assert.Equal(a1.GetHashCode(), a3.GetHashCode()); // The implementation of Attribute.GetHashCode uses reflection to // enumerate fields. On .NET core, we add `BindingFlags.DeclaredOnly` // to fix a bug where the hash code of a subclass of an attribute can // be equal to an instance of the parent class. // See https://github.com/dotnet/coreclr/pull/6240 Assert.False(s1.GetHashCode().Equals(s2.GetHashCode())); Assert.False(s2.GetHashCode().Equals(s3.GetHashCode())); Assert.Equal(s1.GetHashCode(), s3.GetHashCode()); Assert.False(d1.GetHashCode().Equals(d2.GetHashCode())); Assert.False(d2.GetHashCode().Equals(d3.GetHashCode())); Assert.Equal(d1.GetHashCode(), d3.GetHashCode()); Assert.Equal(f1.GetHashCode(), f2.GetHashCode()); Assert.Equal(f2.GetHashCode(), f3.GetHashCode()); Assert.Equal(f1.GetHashCode(), f3.GetHashCode()); Assert.True(d1.GetHashCode().Equals(a1.GetHashCode())); Assert.True(d2.GetHashCode().Equals(a2.GetHashCode())); Assert.True(d3.GetHashCode().Equals(a3.GetHashCode())); Assert.True(d1.GetHashCode().Equals(a3.GetHashCode())); Assert.True(d3.GetHashCode().Equals(a1.GetHashCode())); Assert.True(d1.GetHashCode().Equals(s1.GetHashCode())); Assert.True(d2.GetHashCode().Equals(s2.GetHashCode())); Assert.True(d3.GetHashCode().Equals(s3.GetHashCode())); Assert.True(d1.GetHashCode().Equals(s3.GetHashCode())); Assert.True(d3.GetHashCode().Equals(s1.GetHashCode())); Assert.NotEqual(f1.GetHashCode(), a1.GetHashCode()); Assert.NotEqual(f2.GetHashCode(), a2.GetHashCode()); Assert.NotEqual(f3.GetHashCode(), a3.GetHashCode()); Assert.NotEqual(f1.GetHashCode(), a3.GetHashCode()); Assert.NotEqual(f3.GetHashCode(), a1.GetHashCode()); }
public static void DefaultEquality() { var a1 = new ParentAttribute { Prop = 1 }; var a2 = new ParentAttribute { Prop = 42 }; var a3 = new ParentAttribute { Prop = 1 }; var d1 = new ChildAttribute { Prop = 1 }; var d2 = new ChildAttribute { Prop = 42 }; var d3 = new ChildAttribute { Prop = 1 }; var s1 = new GrandchildAttribute { Prop = 1 }; var s2 = new GrandchildAttribute { Prop = 42 }; var s3 = new GrandchildAttribute { Prop = 1 }; var f1 = new ChildAttributeWithField { Prop = 1 }; var f2 = new ChildAttributeWithField { Prop = 42 }; var f3 = new ChildAttributeWithField { Prop = 1 }; Assert.NotEqual(a1, a2); Assert.NotEqual(a2, a3); Assert.Equal(a1, a3); // The implementation of Attribute.Equals uses reflection to // enumerate fields. On .NET core, we add `BindingFlags.DeclaredOnly` // to fix a bug where an instance of a subclass of an attribute can // be equal to an instance of the parent class. // See https://github.com/dotnet/coreclr/pull/6240 Assert.False(d1.Equals(d2)); Assert.False(d2.Equals(d3)); Assert.Equal(d1, d3); Assert.False(s1.Equals(s2)); Assert.False(s2.Equals(s3)); Assert.Equal(s1, s3); Assert.False(f1.Equals(f2)); Assert.False(f2.Equals(f3)); Assert.Equal(f1, f3); Assert.NotEqual(d1, a1); Assert.NotEqual(d2, a2); Assert.NotEqual(d3, a3); Assert.NotEqual(d1, a3); Assert.NotEqual(d3, a1); Assert.NotEqual(d1, s1); Assert.NotEqual(d2, s2); Assert.NotEqual(d3, s3); Assert.NotEqual(d1, s3); Assert.NotEqual(d3, s1); Assert.NotEqual(f1, a1); Assert.NotEqual(f2, a2); Assert.NotEqual(f3, a3); Assert.NotEqual(f1, a3); Assert.NotEqual(f3, a1); }
public TypeSchema(Type type) { this.type = type; propertySchemas = new Hashtable(); parentSchemas = new Hashtable(); childSchemas = new Hashtable(); Trace.WriteLineIf(DebugOutput.Enabled, "Creating TypeSchema for " + type.FullName); if (!type.IsSubclassOf(typeof(ServerObject))) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "{0} is not a subclass of ServerObject.", type.FullName)); } if (type.GetCustomAttributes(typeof(TableAttribute), false).Length != 1) { throw new ObjectServerException("Could not locate TableAttribute on type " + type.FullName); } if (!type.IsAbstract) { throw new ObjectServerException(type.FullName + " is not an abstract class"); } tableData = (TableAttribute)type.GetCustomAttributes(typeof(TableAttribute), false)[0]; Debug.Indent(); Trace.WriteLineIf(DebugOutput.Enabled, "TableName = " + tableData.TableName); Trace.WriteLineIf(DebugOutput.Enabled, "PrimaryKey = " + tableData.PrimaryKey); Trace.WriteLineIf(DebugOutput.Enabled, "PrimaryKeyType = " + tableData.KeyType); Trace.WriteLineIf(DebugOutput.Enabled, "DefaultOrder = " + tableData.DefaultOrder); Debug.Unindent(); PropertyInfo keyProperty = type.GetProperty(tableData.PrimaryKey, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (keyProperty == null) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "Could not locate the property {0} which is defined as the property for {1}", tableData.PrimaryKey, type.FullName)); } if (tableData.KeyType == PrimaryKeyType.Identity && keyProperty.PropertyType != typeof(int)) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "KeyType equals PrimaryKeyType.Identity and the property {0}.{1} is not System.Int32", type.FullName, keyProperty.Name)); } if (tableData.KeyType == PrimaryKeyType.Guid && keyProperty.PropertyType != typeof(Guid)) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "KeyType equals PrimaryKeyType.Guid and the property {0}.{1} is not System.Guid", type.FullName, keyProperty.Name)); } foreach (PropertyInfo propInfo in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { Trace.WriteLineIf(DebugOutput.Enabled, "Checking property " + propInfo.Name); if (propInfo.GetCustomAttributes(typeof(ColumnAttribute), false).Length == 1) { if (propInfo.GetIndexParameters().Length != 0) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "Index properties ({0}.{1}) cannot be attributed with ColumnAttribute", type.FullName, propInfo.Name)); } if (!propInfo.CanRead) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "{0}.{1} must have an accessor", type.FullName, propInfo.Name)); } if (!propInfo.GetGetMethod(true).IsAbstract) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "{0}.{1} must be abstract", type.FullName, propInfo.Name)); } ColumnAttribute columnData = (ColumnAttribute)propInfo.GetCustomAttributes(typeof(ColumnAttribute), false)[0]; Debug.Indent(); Trace.WriteLineIf(DebugOutput.Enabled, "ColumnName = " + columnData.ColumnName);; Trace.WriteLineIf(DebugOutput.Enabled, "NullValue = " + columnData.NullValue); Debug.Unindent(); if (propInfo.Name == tableData.PrimaryKey && columnData.NullValue != null) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "{0}.{1} is marked as the Primary Key and cannot have a NullValue", type.FullName, propInfo.Name)); } propertySchemas.Add(propInfo.Name, new PropertySchema(this, propInfo, columnData)); } else if (propInfo.GetCustomAttributes(typeof(ParentAttribute), false).Length == 1) { if (propInfo.GetIndexParameters().Length != 0) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "Index properties ({0}.{1}) cannot be attributed with ParentAttribute", type.FullName, propInfo.Name)); } if (!propInfo.CanRead) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "{0}.{1} must have an accessor", type.FullName, propInfo.Name)); } if (!propInfo.GetGetMethod(true).IsAbstract) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "{0}.{1} must be abstract", type.FullName, propInfo.Name)); } ParentAttribute parentData = (ParentAttribute)propInfo.GetCustomAttributes(typeof(ParentAttribute), false)[0]; if (parentData.DeleteAction == DeleteAction.Null && !parentData.CanBeNull) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "{0}.{1} has DeleteAction.Null and CanBeNull is false", type.FullName, propInfo.Name)); } Debug.Indent(); Trace.WriteLineIf(DebugOutput.Enabled, "ColumnName = " + parentData.ColumnName); Trace.WriteLineIf(DebugOutput.Enabled, "ActionOnDelete = " + parentData.DeleteAction); Debug.Unindent(); parentSchemas.Add(propInfo.Name, new ParentSchema(this, propInfo, parentData)); } else if (propInfo.GetCustomAttributes(typeof(ChildrenAttribute), false).Length == 1) { if (propInfo.GetIndexParameters().Length != 0) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "Index properties ({0}.{1}) cannot be attributed with ChildrenAttribute", type.FullName, propInfo.Name)); } if (!propInfo.CanRead) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "{0}.{1} must have an accessor", type.FullName, propInfo.Name)); } if (propInfo.CanWrite) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "{0}.{1} must be read only", type.FullName, propInfo.Name)); } if (!propInfo.GetGetMethod(true).IsAbstract) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "{0}.{1} must be abstract", type.FullName, propInfo.Name)); } if (propInfo.PropertyType != typeof(ServerObjectCollection)) { throw new ObjectServerException(String.Format(CultureInfo.CurrentCulture, "{0}.{1} must be of type ServerObjectCollection", type.FullName, propInfo.Name)); } ChildrenAttribute childData = (ChildrenAttribute)propInfo.GetCustomAttributes(typeof(ChildrenAttribute), false)[0]; Debug.Indent(); Trace.WriteLineIf(DebugOutput.Enabled, "ChildType = " + childData.ChildType.FullName); Trace.WriteLineIf(DebugOutput.Enabled, "PropertyName = " + childData.PropertyName); Debug.Unindent(); childSchemas.Add(propInfo.Name, new ChildrenSchema(this, propInfo, childData)); } } proxyType = ProxyBuilder.BuildProxy(type); }