private void GenerateConfigurationElementCollectionCode(ConfigurationElement element, CodeTypeDeclaration elementClass) { ConfigurationElementCollection collectionElement = (ConfigurationElementCollection)element; ConfigurationProperty keyProperty = collectionElement.ItemType.KeyProperties.Single(); string xmlPropertyName = string.Format("{0}PropertyName", collectionElement.ItemType.Name); string configurationElementTypeReference = GetTypeReferenceString(typeof(System.Configuration.ConfigurationElement)); string configurationElementCollectionTypeReference = GetTypeReferenceString(typeof(System.Configuration.ConfigurationElementCollection)); CodeTypeReference collectionItemType = GlobalSelfReference(collectionElement.ItemType.FullName); string collectionItemTypeReference = GetTypeSelfReferenceString(collectionElement.ItemType.FullName); CodeTypeReference icollectionTypeReference = null; if ((collectionElement.CodeGenOptions & ConfigurationElementCollectionCodeGenOptions.ICollection) == ConfigurationElementCollectionCodeGenOptions.ICollection) { icollectionTypeReference = new CodeTypeReference(string.Concat("global::System.Collections.Generic.ICollection<", collectionItemTypeReference, ">")); elementClass.BaseTypes.Add(icollectionTypeReference); } // Add ConfigurationCollectionAttribute CodeAttributeDeclaration collectionType = new CodeAttributeDeclaration( GlobalReference(typeof(System.Configuration.ConfigurationCollectionAttribute)), new CodeAttributeArgument(_selftypeof(collectionElement.ItemType.FullName)), new CodeAttributeArgument("CollectionType", new CodeFieldReferenceExpression( GlobalReferenceExpression(collectionElement.CollectionType.GetType()), Enum.GetName(collectionElement.CollectionType.GetType(), collectionElement.CollectionType) ) ) ); if (collectionElement.CollectionType == System.Configuration.ConfigurationElementCollectionType.BasicMap || collectionElement.CollectionType == System.Configuration.ConfigurationElementCollectionType.BasicMapAlternate) { collectionType.Arguments.Add( new CodeAttributeArgument("AddItemName", new CodeFieldReferenceExpression( GlobalSelfReferenceExpression(element.FullName), xmlPropertyName ) ) ); } else { collectionType.Arguments.Add( new CodeAttributeArgument("AddItemName", new CodePrimitiveExpression(collectionElement.AddItemName) ) ); collectionType.Arguments.Add( new CodeAttributeArgument("RemoveItemName", new CodePrimitiveExpression(collectionElement.RemoveItemName) ) ); collectionType.Arguments.Add( new CodeAttributeArgument("ClearItemsName", new CodePrimitiveExpression(collectionElement.ClearItemsName) ) ); } elementClass.CustomAttributes.Add(collectionType); // Add XmlName field CodeMemberField xmlNameField = new CodeMemberField(_string, xmlPropertyName); elementClass.Members.Add(xmlNameField); xmlNameField.StartDirectives.Add(Region("Constants")); xmlNameField.Comments.Add(DocComment("<summary>")); xmlNameField.Comments.Add(DocComment(string.Format("The XML name of the individual <see cref=\"{0}\"/> instances in this collection.", collectionItemTypeReference))); xmlNameField.Comments.Add(DocComment("</summary>")); xmlNameField.CustomAttributes.Add(_generatedCodeAttribute); xmlNameField.Attributes = MemberAttributes.Const | MemberAttributes.Assembly; xmlNameField.InitExpression = new CodePrimitiveExpression(collectionElement.XmlItemName); xmlNameField.EndDirectives.Add(EndRegion()); // Add collection type property CodeMemberProperty collectionTypeProperty = new CodeMemberProperty(); elementClass.Members.Add(collectionTypeProperty); collectionTypeProperty.StartDirectives.Add(Region("Overrides")); collectionTypeProperty.Comments.Add(DocComment("<summary>")); collectionTypeProperty.Comments.Add(DocComment(string.Format("Gets the type of the <see cref=\"{0}\"/>.", configurationElementCollectionTypeReference))); collectionTypeProperty.Comments.Add(DocComment("</summary>")); collectionTypeProperty.Comments.Add(DocComment(string.Format("<returns>The <see cref=\"{0}\"/> of this collection.</returns>", GetTypeReferenceString(typeof(System.Configuration.ConfigurationElementCollectionType))))); collectionTypeProperty.CustomAttributes.Add(_generatedCodeAttribute); collectionTypeProperty.Attributes = MemberAttributes.Public | MemberAttributes.Override; collectionTypeProperty.Type = GlobalReference(typeof(System.Configuration.ConfigurationElementCollectionType)); collectionTypeProperty.Name = "CollectionType"; collectionTypeProperty.HasGet = true; collectionTypeProperty.GetStatements.Add( new CodeMethodReturnStatement( new CodeFieldReferenceExpression( GlobalReferenceExpression(collectionElement.CollectionType.GetType()), Enum.GetName(collectionElement.CollectionType.GetType(), collectionElement.CollectionType) ) ) ); // Add ElementName property CodeMemberProperty elementNameProperty = new CodeMemberProperty(); elementClass.Members.Add(elementNameProperty); elementNameProperty.Comments.Add(DocComment("<summary>")); elementNameProperty.Comments.Add(DocComment("Gets the name used to identify this collection of elements")); elementNameProperty.Comments.Add(DocComment("</summary>")); elementNameProperty.CustomAttributes.Add(_generatedCodeAttribute); elementNameProperty.Attributes = MemberAttributes.Family | MemberAttributes.Override; elementNameProperty.Type = _string; elementNameProperty.Name = "ElementName"; elementNameProperty.HasGet = true; elementNameProperty.GetStatements.Add( new CodeMethodReturnStatement( new CodeFieldReferenceExpression( GlobalSelfReferenceExpression(element.FullName), xmlPropertyName ) ) ); // Add IsElementName method CodeMemberMethod isElementNameMethod = new CodeMemberMethod(); elementClass.Members.Add(isElementNameMethod); isElementNameMethod.Comments.Add(DocComment("<summary>")); isElementNameMethod.Comments.Add(DocComment(string.Format("Indicates whether the specified <see cref=\"{0}\"/> exists in the <see cref=\"{1}\"/>.", configurationElementTypeReference, configurationElementCollectionTypeReference))); isElementNameMethod.Comments.Add(DocComment("</summary>")); isElementNameMethod.Comments.Add(DocComment("<param name=\"elementName\">The name of the element to verify.</param>")); isElementNameMethod.Comments.Add(DocComment("<returns>")); isElementNameMethod.Comments.Add(DocComment("<see langword=\"true\"/> if the element exists in the collection; otherwise, <see langword=\"false\"/>.")); isElementNameMethod.Comments.Add(DocComment("</returns>")); isElementNameMethod.CustomAttributes.Add(_generatedCodeAttribute); isElementNameMethod.Attributes = MemberAttributes.Family | MemberAttributes.Override; isElementNameMethod.ReturnType = GlobalReference(typeof(bool)); isElementNameMethod.Name = "IsElementName"; isElementNameMethod.Parameters.Add(new CodeParameterDeclarationExpression(_string, "elementName")); isElementNameMethod.Statements.Add( new CodeMethodReturnStatement( new CodeBinaryOperatorExpression( new CodeArgumentReferenceExpression("elementName"), CodeBinaryOperatorType.ValueEquality, new CodeFieldReferenceExpression( GlobalSelfReferenceExpression(string.Format("{0}.{1}", element.ActualNamespace, element.Name)), xmlNameField.Name ) ) ) ); // Add GetElementKey method CodeMemberMethod getElementKeyMethod = new CodeMemberMethod(); elementClass.Members.Add(getElementKeyMethod); getElementKeyMethod.Comments.Add(DocComment("<summary>")); getElementKeyMethod.Comments.Add(DocComment("Gets the element key for the specified configuration element.")); getElementKeyMethod.Comments.Add(DocComment("</summary>")); getElementKeyMethod.Comments.Add(DocComment(string.Format("<param name=\"element\">The <see cref=\"{0}\"/> to return the key for.</param>", configurationElementTypeReference))); getElementKeyMethod.Comments.Add(DocComment("<returns>")); getElementKeyMethod.Comments.Add(DocComment(string.Format("An <see cref=\"{0}\"/> that acts as the key for the specified <see cref=\"{1}\"/>.", GetTypeReferenceString(typeof(object)), configurationElementTypeReference))); getElementKeyMethod.Comments.Add(DocComment("</returns>")); getElementKeyMethod.CustomAttributes.Add(_generatedCodeAttribute); getElementKeyMethod.Attributes = MemberAttributes.Family | MemberAttributes.Override; getElementKeyMethod.ReturnType = _object; getElementKeyMethod.Name = "GetElementKey"; getElementKeyMethod.Parameters.Add(new CodeParameterDeclarationExpression(GlobalReference(typeof(System.Configuration.ConfigurationElement)), "element")); getElementKeyMethod.Statements.Add( new CodeMethodReturnStatement( new CodeFieldReferenceExpression( new CodeCastExpression( GlobalSelfReference(collectionElement.ItemType.FullName), new CodeArgumentReferenceExpression("element") ), keyProperty.Name ) ) ); // Add CreateNewElement method CodeMemberMethod createNewElementMethod = new CodeMemberMethod(); elementClass.Members.Add(createNewElementMethod); createNewElementMethod.Comments.Add(DocComment("<summary>")); createNewElementMethod.Comments.Add(DocComment(string.Format("Creates a new <see cref=\"{0}\"/>.", collectionItemTypeReference))); createNewElementMethod.Comments.Add(DocComment("</summary>")); createNewElementMethod.Comments.Add(DocComment("<returns>")); createNewElementMethod.Comments.Add(DocComment(string.Format("A new <see cref=\"{0}\"/>.", collectionItemTypeReference))); createNewElementMethod.Comments.Add(DocComment("</returns>")); createNewElementMethod.CustomAttributes.Add(_generatedCodeAttribute); createNewElementMethod.Attributes = MemberAttributes.Family | MemberAttributes.Override; createNewElementMethod.ReturnType = GlobalReference(typeof(System.Configuration.ConfigurationElement)); createNewElementMethod.Name = "CreateNewElement"; createNewElementMethod.Statements.Add( new CodeMethodReturnStatement(new CodeObjectCreateExpression(collectionItemType)) ); createNewElementMethod.EndDirectives.Add(EndRegion()); if ((collectionElement.CodeGenOptions & ConfigurationElementCollectionCodeGenOptions.Indexer) == ConfigurationElementCollectionCodeGenOptions.Indexer) { // Add indexer for location CodeMemberProperty locationIndexerProperty = new CodeMemberProperty(); elementClass.Members.Add(locationIndexerProperty); locationIndexerProperty.StartDirectives.Add(Region("Indexer")); locationIndexerProperty.Comments.Add(DocComment("<summary>")); locationIndexerProperty.Comments.Add(DocComment(string.Format("Gets the <see cref=\"{0}\"/> at the specified index.", collectionItemTypeReference))); locationIndexerProperty.Comments.Add(DocComment("</summary>")); locationIndexerProperty.Comments.Add(DocComment(string.Format("<param name=\"index\">The index of the <see cref=\"{0}\"/> to retrieve.</param>", collectionItemTypeReference))); locationIndexerProperty.CustomAttributes.Add(_generatedCodeAttribute); locationIndexerProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Overloaded; locationIndexerProperty.Type = GlobalSelfReference(collectionElement.ItemType.FullName); locationIndexerProperty.Name = "Item"; locationIndexerProperty.Parameters.Add(new CodeParameterDeclarationExpression(_int, "index")); locationIndexerProperty.HasGet = true; locationIndexerProperty.GetStatements.Add( new CodeMethodReturnStatement( new CodeCastExpression( collectionItemType, new CodeMethodInvokeExpression( _base, "BaseGet", new CodeArgumentReferenceExpression("index") ) ) ) ); // Add GetItemByKey method CodeMemberProperty keyIndexerProperty = new CodeMemberProperty(); elementClass.Members.Add(keyIndexerProperty); keyIndexerProperty.Comments.Add(DocComment("<summary>")); keyIndexerProperty.Comments.Add(DocComment(string.Format("Gets the <see cref=\"{0}\"/> with the specified key.", collectionItemTypeReference))); keyIndexerProperty.Comments.Add(DocComment("</summary>")); keyIndexerProperty.Comments.Add(DocComment(string.Format("<param name=\"{0}\">The key of the <see cref=\"{1}\"/> to retrieve.</param>", keyProperty.XmlName, collectionItemTypeReference))); keyIndexerProperty.CustomAttributes.Add(_generatedCodeAttribute); keyIndexerProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Overloaded; keyIndexerProperty.Type = collectionItemType; keyIndexerProperty.Name = "Item"; keyIndexerProperty.Parameters.Add(new CodeParameterDeclarationExpression(_object, keyProperty.XmlName)); keyIndexerProperty.GetStatements.Add( new CodeMethodReturnStatement( new CodeCastExpression( collectionItemType, new CodeMethodInvokeExpression( _base, "BaseGet", new CodeArgumentReferenceExpression(keyProperty.XmlName) ) ) ) ); keyIndexerProperty.EndDirectives.Add(EndRegion()); } if ((collectionElement.CodeGenOptions & ConfigurationElementCollectionCodeGenOptions.AddMethod) == ConfigurationElementCollectionCodeGenOptions.AddMethod || (collectionElement.CodeGenOptions & ConfigurationElementCollectionCodeGenOptions.ICollection) == ConfigurationElementCollectionCodeGenOptions.ICollection) { // Add Add method CodeMemberMethod addMethod = new CodeMemberMethod(); elementClass.Members.Add(addMethod); addMethod.StartDirectives.Add(Region("Add")); addMethod.Comments.Add(DocComment("<summary>")); addMethod.Comments.Add(DocComment(string.Format("Adds the specified <see cref=\"{0}\"/> to the <see cref=\"{1}\"/>.", collectionItemTypeReference, configurationElementCollectionTypeReference))); addMethod.Comments.Add(DocComment("</summary>")); addMethod.Comments.Add(DocComment(string.Format("<param name=\"{0}\">The <see cref=\"{1}\"/> to add.</param>", collectionElement.XmlItemName, collectionItemTypeReference))); addMethod.CustomAttributes.Add(_generatedCodeAttribute); addMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; addMethod.ReturnType = _void; addMethod.Name = "Add"; addMethod.Parameters.Add(new CodeParameterDeclarationExpression(GlobalSelfReference(collectionElement.ItemType.FullName), collectionElement.XmlItemName)); addMethod.Statements.Add( new CodeMethodInvokeExpression( _base, "BaseAdd", new CodeArgumentReferenceExpression(collectionElement.XmlItemName) ) ); addMethod.EndDirectives.Add(EndRegion()); } if ((collectionElement.CodeGenOptions & ConfigurationElementCollectionCodeGenOptions.RemoveMethod) == ConfigurationElementCollectionCodeGenOptions.RemoveMethod || (collectionElement.CodeGenOptions & ConfigurationElementCollectionCodeGenOptions.ICollection) == ConfigurationElementCollectionCodeGenOptions.ICollection) { // Add Remove method CodeMemberMethod removeMethod = new CodeMemberMethod(); elementClass.Members.Add(removeMethod); removeMethod.StartDirectives.Add(Region("Remove")); removeMethod.Comments.Add(DocComment("<summary>")); removeMethod.Comments.Add(DocComment(string.Format("Removes the specified <see cref=\"{0}\"/> from the <see cref=\"{1}\"/>.", collectionItemTypeReference, configurationElementCollectionTypeReference))); removeMethod.Comments.Add(DocComment("</summary>")); removeMethod.Comments.Add(DocComment(string.Format("<param name=\"{0}\">The <see cref=\"{1}\"/> to remove.</param>", collectionElement.XmlItemName, collectionItemTypeReference))); removeMethod.CustomAttributes.Add(_generatedCodeAttribute); removeMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; removeMethod.ReturnType = _void; removeMethod.Name = "Remove"; removeMethod.Parameters.Add(new CodeParameterDeclarationExpression(collectionItemType, collectionElement.XmlItemName)); removeMethod.Statements.Add( new CodeMethodInvokeExpression( _base, "BaseRemove", new CodeMethodInvokeExpression( _this, "GetElementKey", new CodeArgumentReferenceExpression(collectionElement.XmlItemName) ) ) ); removeMethod.EndDirectives.Add(EndRegion()); } if ((collectionElement.CodeGenOptions & ConfigurationElementCollectionCodeGenOptions.GetItemMethods) == ConfigurationElementCollectionCodeGenOptions.GetItemMethods) { // Add GetItemAt method CodeMemberMethod getItemAtMethod = new CodeMemberMethod(); elementClass.Members.Add(getItemAtMethod); getItemAtMethod.StartDirectives.Add(Region("GetItem")); getItemAtMethod.Comments.Add(DocComment("<summary>")); getItemAtMethod.Comments.Add(DocComment(string.Format("Gets the <see cref=\"{0}\"/> at the specified index.", collectionItemTypeReference))); getItemAtMethod.Comments.Add(DocComment("</summary>")); getItemAtMethod.Comments.Add(DocComment(string.Format("<param name=\"index\">The index of the <see cref=\"{0}\"/> to retrieve.</param>", collectionItemTypeReference))); getItemAtMethod.CustomAttributes.Add(_generatedCodeAttribute); getItemAtMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; getItemAtMethod.ReturnType = collectionItemType; getItemAtMethod.Name = "GetItemAt"; getItemAtMethod.Parameters.Add(new CodeParameterDeclarationExpression(_int, "index")); getItemAtMethod.Statements.Add( new CodeMethodReturnStatement( new CodeCastExpression( collectionItemType, new CodeMethodInvokeExpression( _base, "BaseGet", new CodeArgumentReferenceExpression("index") ) ) ) ); // Add GetItemByKey method CodeMemberMethod getItemByKeyMethod = new CodeMemberMethod(); elementClass.Members.Add(getItemByKeyMethod); getItemByKeyMethod.Comments.Add(DocComment("<summary>")); getItemByKeyMethod.Comments.Add(DocComment(string.Format("Gets the <see cref=\"{0}\"/> with the specified key.", collectionItemTypeReference))); getItemByKeyMethod.Comments.Add(DocComment("</summary>")); getItemByKeyMethod.Comments.Add(DocComment(string.Format("<param name=\"{0}\">The key of the <see cref=\"{1}\"/> to retrieve.</param>", keyProperty.XmlName, collectionItemTypeReference))); getItemByKeyMethod.CustomAttributes.Add(_generatedCodeAttribute); getItemByKeyMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; getItemByKeyMethod.ReturnType = collectionItemType; getItemByKeyMethod.Name = "GetItemByKey"; getItemByKeyMethod.Parameters.Add(new CodeParameterDeclarationExpression(GlobalReference(keyProperty.TypeName), keyProperty.XmlName)); getItemByKeyMethod.Statements.Add( new CodeMethodReturnStatement( new CodeCastExpression( collectionItemType, new CodeMethodInvokeExpression( _base, "BaseGet", new CodeCastExpression( _object, new CodeArgumentReferenceExpression(keyProperty.XmlName) ) ) ) ) ); getItemByKeyMethod.EndDirectives.Add(EndRegion()); } if ((collectionElement.CodeGenOptions & ConfigurationElementCollectionCodeGenOptions.ICollection) == ConfigurationElementCollectionCodeGenOptions.ICollection) { // Add Clear method CodeMemberMethod clearMethod = new CodeMemberMethod(); elementClass.Members.Add(clearMethod); clearMethod.StartDirectives.Add(Region("ICollection")); clearMethod.Comments.Add(DocComment("<summary>")); clearMethod.Comments.Add(DocComment(string.Format("Removes all items from the <see cref=\"{0}\"/>.", configurationElementCollectionTypeReference))); clearMethod.Comments.Add(DocComment("</summary>")); clearMethod.CustomAttributes.Add(_generatedCodeAttribute); clearMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; clearMethod.ReturnType = _void; clearMethod.Name = "Clear"; clearMethod.Statements.Add( new CodeMethodInvokeExpression(_base, "BaseClear") ); //Add Contains method CodeMemberMethod containsMethod = new CodeMemberMethod(); elementClass.Members.Add(containsMethod); containsMethod.Comments.Add(DocComment("<summary>")); containsMethod.Comments.Add(DocComment(string.Format("Determines whether the <see cref=\"{0}\"/> contains a specific value.", configurationElementCollectionTypeReference))); containsMethod.Comments.Add(DocComment("</summary>")); containsMethod.Comments.Add(DocComment(string.Format("<param name=\"{0}\">The object to locate in the <see cref=\"{1}\"/>.</param>", collectionElement.XmlItemName, collectionItemTypeReference))); containsMethod.CustomAttributes.Add(_generatedCodeAttribute); containsMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; containsMethod.ReturnType = _bool; containsMethod.Name = "Contains"; containsMethod.Parameters.Add(new CodeParameterDeclarationExpression(collectionItemType, collectionElement.XmlItemName)); containsMethod.Statements.Add( new CodeMethodReturnStatement( new CodeBinaryOperatorExpression( new CodeMethodInvokeExpression(_base, "BaseIndexOf", new CodeArgumentReferenceExpression(collectionElement.XmlItemName)), CodeBinaryOperatorType.GreaterThanOrEqual, new CodePrimitiveExpression(0) ) ) ); //Add CopyTo method CodeMemberMethod copytoMethod = new CodeMemberMethod(); elementClass.Members.Add(copytoMethod); copytoMethod.Comments.Add(DocComment("<summary>")); copytoMethod.Comments.Add(DocComment(string.Format("Copies the elements of the <see cref=\"{0}\"/> to an <see cref=\"System.Array\"/>, starting at a particular <see cref=\"System.Array\"/> index.", configurationElementCollectionTypeReference))); copytoMethod.Comments.Add(DocComment("</summary>")); copytoMethod.Comments.Add(DocComment(string.Format("<param name=\"array\">The one-dimensional <see cref=\"System.Array\"/> that is the destination of the elements copied from <see cref=\"{0}\"/>. The <see cref=\"System.Array\"/> must have zero-based indexing.</param>", configurationElementCollectionTypeReference))); copytoMethod.Comments.Add(DocComment("<param name=\"arrayIndex\">The zero-based index in <paramref name=\"array\"/> at which copying begins.</param>")); copytoMethod.CustomAttributes.Add(_generatedCodeAttribute); copytoMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; copytoMethod.ReturnType = _void; copytoMethod.Name = "CopyTo"; copytoMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(collectionItemTypeReference, 1), "array")); copytoMethod.Parameters.Add(new CodeParameterDeclarationExpression(_int, "arrayIndex")); copytoMethod.Statements.Add( new CodeMethodInvokeExpression(_base, "CopyTo", new CodeArgumentReferenceExpression("array"), new CodeArgumentReferenceExpression("arrayIndex")) ); //Add ICollection.IsReadOnly property CodeMemberProperty isReadOnlyProperty = new CodeMemberProperty(); elementClass.Members.Add(isReadOnlyProperty); isReadOnlyProperty.Comments.Add(DocComment("<summary>")); isReadOnlyProperty.Comments.Add(DocComment(string.Format("Gets a value indicating whether the <see cref=\"{0}\"/> is read-only.", configurationElementCollectionTypeReference))); isReadOnlyProperty.Comments.Add(DocComment("</summary>")); isReadOnlyProperty.CustomAttributes.Add(_generatedCodeAttribute); isReadOnlyProperty.Attributes = MemberAttributes.Private; isReadOnlyProperty.PrivateImplementationType = icollectionTypeReference; isReadOnlyProperty.Type = _bool; isReadOnlyProperty.HasGet = true; isReadOnlyProperty.HasSet = false; isReadOnlyProperty.Name = "IsReadOnly"; isReadOnlyProperty.GetStatements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression(_this, "IsReadOnly") ) ); //Add ICollection.Remove method CodeMemberMethod icRemoveMethod = new CodeMemberMethod(); elementClass.Members.Add(icRemoveMethod); icRemoveMethod.Comments.Add(DocComment("<summary>")); icRemoveMethod.Comments.Add(DocComment(string.Format("Removes the first occurrence of a specific object from the <see cref=\"{0}\"/>.", configurationElementCollectionTypeReference))); icRemoveMethod.Comments.Add(DocComment("</summary>")); icRemoveMethod.Comments.Add(DocComment(string.Format("<param name=\"item\">The <see cref=\"{0}\"/> to remove.</param>", collectionItemTypeReference))); icRemoveMethod.CustomAttributes.Add(_generatedCodeAttribute); icRemoveMethod.Attributes = MemberAttributes.Private; icRemoveMethod.PrivateImplementationType = icollectionTypeReference; icRemoveMethod.ReturnType = _bool; icRemoveMethod.Name = "Remove"; icRemoveMethod.Parameters.Add(new CodeParameterDeclarationExpression(collectionItemType, "item")); icRemoveMethod.Statements.Add( new CodeVariableDeclarationStatement(_int, "idx", new CodeMethodInvokeExpression(_base, "BaseIndexOf", new CodeArgumentReferenceExpression("item")) ) ); icRemoveMethod.Statements.Add( new CodeConditionStatement( new CodeBinaryOperatorExpression( new CodeVariableReferenceExpression("idx"), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(-1) ), new CodeMethodReturnStatement(new CodePrimitiveExpression(false)) ) ); icRemoveMethod.Statements.Add( new CodeMethodInvokeExpression(_base, "BaseRemoveAt", new CodeVariableReferenceExpression("idx")) ); icRemoveMethod.Statements.Add( new CodeMethodReturnStatement(new CodePrimitiveExpression(true)) ); //Add IEnumerator<> method CodeTypeReference ienumTypeReference = new CodeTypeReference(typeof(System.Collections.Generic.IEnumerator <>), CodeTypeReferenceOptions.GlobalReference); ienumTypeReference.Options = CodeTypeReferenceOptions.GlobalReference | CodeTypeReferenceOptions.GenericTypeParameter; ienumTypeReference.TypeArguments.Add(collectionItemType); CodeTypeReference listTypeReference = new CodeTypeReference(typeof(System.Collections.Generic.List <>), CodeTypeReferenceOptions.GlobalReference); listTypeReference.Options = CodeTypeReferenceOptions.GlobalReference | CodeTypeReferenceOptions.GenericTypeParameter; listTypeReference.TypeArguments.Add(collectionItemType); CodeMemberMethod getEnumeratorMethod = new CodeMemberMethod(); elementClass.Members.Add(getEnumeratorMethod); getEnumeratorMethod.Comments.Add(DocComment("<summary>")); getEnumeratorMethod.Comments.Add(DocComment("Returns an enumerator that iterates through the collection.")); getEnumeratorMethod.Comments.Add(DocComment("</summary>")); getEnumeratorMethod.CustomAttributes.Add(_generatedCodeAttribute); getEnumeratorMethod.Attributes = MemberAttributes.New | MemberAttributes.Public | MemberAttributes.Final; getEnumeratorMethod.ReturnType = ienumTypeReference; getEnumeratorMethod.Name = "GetEnumerator"; getEnumeratorMethod.Statements.Add( new CodeVariableDeclarationStatement(listTypeReference, "list", new CodeObjectCreateExpression(listTypeReference, new CodePropertyReferenceExpression(_base, "Count")) ) ); CodeVariableReferenceExpression varList = new CodeVariableReferenceExpression("list"); getEnumeratorMethod.Statements.Add( new CodeVariableDeclarationStatement(GlobalReference(typeof(System.Collections.IEnumerator)), "iter", new CodeMethodInvokeExpression(_base, "GetEnumerator") ) ); CodeVariableReferenceExpression varIter = new CodeVariableReferenceExpression("iter"); CodeExpressionStatement emptyExpr = new CodeExpressionStatement(new CodeSnippetExpression()); getEnumeratorMethod.Statements.Add( new CodeIterationStatement( emptyExpr, new CodeMethodInvokeExpression(varIter, "MoveNext"), emptyExpr, new CodeExpressionStatement( new CodeMethodInvokeExpression( varList, "Add", new CodeCastExpression(collectionItemType, new CodePropertyReferenceExpression(varIter, "Current")) ) ) ) ); getEnumeratorMethod.Statements.Add( new CodeMethodReturnStatement(new CodeMethodInvokeExpression(varList, "GetEnumerator") ) ); getEnumeratorMethod.EndDirectives.Add(EndRegion()); } }
private void GenerateConfigurationElementCollectionCode(ConfigurationElement element, CodeTypeDeclaration elementClass) { ConfigurationElementCollection collectionElement = (ConfigurationElementCollection)element; ConfigurationProperty keyProperty = collectionElement.ItemType.KeyProperties.Single(); string xmlPropertyName = string.Format("{0}PropertyName", collectionElement.ItemType.Name); string configurationElementTypeReference = GetTypeReferenceString(typeof(System.Configuration.ConfigurationElement)); string configurationElementCollectionTypeReference = GetTypeReferenceString(typeof(System.Configuration.ConfigurationElementCollection)); CodeTypeReference collectionItemType = GlobalSelfReference(collectionElement.ItemType.FullName); string collectionItemTypeReference = GetTypeSelfReferenceString(collectionElement.ItemType.FullName); // Add ConfigurationCollectionAttribute CodeAttributeDeclaration collectionType = new CodeAttributeDeclaration( GlobalReference(typeof(System.Configuration.ConfigurationCollectionAttribute)), new CodeAttributeArgument(_selftypeof(collectionElement.ItemType.FullName)), new CodeAttributeArgument("CollectionType", new CodeFieldReferenceExpression( GlobalReferenceExpression(collectionElement.CollectionType.GetType()), Enum.GetName(collectionElement.CollectionType.GetType(), collectionElement.CollectionType) ) ) ); if (collectionElement.CollectionType == System.Configuration.ConfigurationElementCollectionType.BasicMap || collectionElement.CollectionType == System.Configuration.ConfigurationElementCollectionType.BasicMapAlternate) { collectionType.Arguments.Add( new CodeAttributeArgument("AddItemName", new CodeFieldReferenceExpression( GlobalSelfReferenceExpression(element.FullName), xmlPropertyName ) ) ); } else { collectionType.Arguments.Add( new CodeAttributeArgument("AddItemName", new CodePrimitiveExpression(collectionElement.AddItemName) ) ); collectionType.Arguments.Add( new CodeAttributeArgument("RemoveItemName", new CodePrimitiveExpression(collectionElement.RemoveItemName) ) ); collectionType.Arguments.Add( new CodeAttributeArgument("ClearItemsName", new CodePrimitiveExpression(collectionElement.ClearItemsName) ) ); } elementClass.CustomAttributes.Add(collectionType); // Add XmlName field CodeMemberField xmlNameField = new CodeMemberField(_string, xmlPropertyName); elementClass.Members.Add(xmlNameField); xmlNameField.StartDirectives.Add(Region("Constants")); xmlNameField.Comments.Add(DocComment("<summary>")); xmlNameField.Comments.Add(DocComment(string.Format("The XML name of the individual <see cref=\"{0}\"/> instances in this collection.", collectionItemTypeReference))); xmlNameField.Comments.Add(DocComment("</summary>")); xmlNameField.CustomAttributes.Add(_generatedCodeAttribute); xmlNameField.Attributes = MemberAttributes.Const | MemberAttributes.Assembly; xmlNameField.InitExpression = new CodePrimitiveExpression(collectionElement.XmlItemName); xmlNameField.EndDirectives.Add(EndRegion()); // Add collection type property CodeMemberProperty collectionTypeProperty = new CodeMemberProperty(); elementClass.Members.Add(collectionTypeProperty); collectionTypeProperty.StartDirectives.Add(Region("Overrides")); collectionTypeProperty.Comments.Add(DocComment("<summary>")); collectionTypeProperty.Comments.Add(DocComment(string.Format("Gets the type of the <see cref=\"{0}\"/>.", configurationElementCollectionTypeReference))); collectionTypeProperty.Comments.Add(DocComment("</summary>")); collectionTypeProperty.Comments.Add(DocComment(string.Format("<returns>The <see cref=\"{0}\"/> of this collection.</returns>", GetTypeReferenceString(typeof(System.Configuration.ConfigurationElementCollectionType))))); collectionTypeProperty.CustomAttributes.Add(_generatedCodeAttribute); collectionTypeProperty.Attributes = MemberAttributes.Public | MemberAttributes.Override; collectionTypeProperty.Type = GlobalReference(typeof(System.Configuration.ConfigurationElementCollectionType)); collectionTypeProperty.Name = "CollectionType"; collectionTypeProperty.HasGet = true; collectionTypeProperty.GetStatements.Add( new CodeMethodReturnStatement( new CodeFieldReferenceExpression( GlobalReferenceExpression(collectionElement.CollectionType.GetType()), Enum.GetName(collectionElement.CollectionType.GetType(), collectionElement.CollectionType) ) ) ); // Add ElementName property CodeMemberProperty elementNameProperty = new CodeMemberProperty(); elementClass.Members.Add(elementNameProperty); elementNameProperty.Comments.Add(DocComment("<summary>")); elementNameProperty.Comments.Add(DocComment("Gets the name used to identify this collection of elements")); elementNameProperty.Comments.Add(DocComment("</summary>")); elementNameProperty.CustomAttributes.Add(_generatedCodeAttribute); elementNameProperty.Attributes = MemberAttributes.Family | MemberAttributes.Override; elementNameProperty.Type = _string; elementNameProperty.Name = "ElementName"; elementNameProperty.HasGet = true; elementNameProperty.GetStatements.Add( new CodeMethodReturnStatement( new CodeFieldReferenceExpression( GlobalSelfReferenceExpression(element.FullName), xmlPropertyName ) ) ); // Add IsElementName method CodeMemberMethod isElementNameMethod = new CodeMemberMethod(); elementClass.Members.Add(isElementNameMethod); isElementNameMethod.Comments.Add(DocComment("<summary>")); isElementNameMethod.Comments.Add(DocComment(string.Format("Indicates whether the specified <see cref=\"{0}\"/> exists in the <see cref=\"{1}\"/>.", configurationElementTypeReference, configurationElementCollectionTypeReference))); isElementNameMethod.Comments.Add(DocComment("</summary>")); isElementNameMethod.Comments.Add(DocComment("<param name=\"elementName\">The name of the element to verify.</param>")); isElementNameMethod.Comments.Add(DocComment("<returns>")); isElementNameMethod.Comments.Add(DocComment("<see langword=\"true\"/> if the element exists in the collection; otherwise, <see langword=\"false\"/>.")); isElementNameMethod.Comments.Add(DocComment("</returns>")); isElementNameMethod.CustomAttributes.Add(_generatedCodeAttribute); isElementNameMethod.Attributes = MemberAttributes.Family | MemberAttributes.Override; isElementNameMethod.ReturnType = GlobalReference(typeof(bool)); isElementNameMethod.Name = "IsElementName"; isElementNameMethod.Parameters.Add(new CodeParameterDeclarationExpression(_string, "elementName")); isElementNameMethod.Statements.Add( new CodeMethodReturnStatement( new CodeBinaryOperatorExpression( new CodeArgumentReferenceExpression("elementName"), CodeBinaryOperatorType.ValueEquality, new CodeFieldReferenceExpression( GlobalSelfReferenceExpression(string.Format("{0}.{1}", element.ActualNamespace, element.Name)), xmlNameField.Name ) ) ) ); // Add GetElementKey method CodeMemberMethod getElementKeyMethod = new CodeMemberMethod(); elementClass.Members.Add(getElementKeyMethod); getElementKeyMethod.Comments.Add(DocComment("<summary>")); getElementKeyMethod.Comments.Add(DocComment("Gets the element key for the specified configuration element.")); getElementKeyMethod.Comments.Add(DocComment("</summary>")); getElementKeyMethod.Comments.Add(DocComment(string.Format("<param name=\"element\">The <see cref=\"{0}\"/> to return the key for.</param>", configurationElementTypeReference))); getElementKeyMethod.Comments.Add(DocComment("<returns>")); getElementKeyMethod.Comments.Add(DocComment(string.Format("An <see cref=\"{0}\"/> that acts as the key for the specified <see cref=\"{1}\"/>.", GetTypeReferenceString(typeof(object)), configurationElementTypeReference))); getElementKeyMethod.Comments.Add(DocComment("</returns>")); getElementKeyMethod.CustomAttributes.Add(_generatedCodeAttribute); getElementKeyMethod.Attributes = MemberAttributes.Family | MemberAttributes.Override; getElementKeyMethod.ReturnType = _object; getElementKeyMethod.Name = "GetElementKey"; getElementKeyMethod.Parameters.Add(new CodeParameterDeclarationExpression(GlobalReference(typeof(System.Configuration.ConfigurationElement)), "element")); getElementKeyMethod.Statements.Add( new CodeMethodReturnStatement( new CodeFieldReferenceExpression( new CodeCastExpression( GlobalSelfReference(collectionElement.ItemType.FullName), new CodeArgumentReferenceExpression("element") ), keyProperty.Name ) ) ); // Add CreateNewElement method CodeMemberMethod createNewElementMethod = new CodeMemberMethod(); elementClass.Members.Add(createNewElementMethod); createNewElementMethod.Comments.Add(DocComment("<summary>")); createNewElementMethod.Comments.Add(DocComment(string.Format("Creates a new <see cref=\"{0}\"/>.", collectionItemTypeReference))); createNewElementMethod.Comments.Add(DocComment("</summary>")); createNewElementMethod.Comments.Add(DocComment("<returns>")); createNewElementMethod.Comments.Add(DocComment(string.Format("A new <see cref=\"{0}\"/>.", collectionItemTypeReference))); createNewElementMethod.Comments.Add(DocComment("</returns>")); createNewElementMethod.CustomAttributes.Add(_generatedCodeAttribute); createNewElementMethod.Attributes = MemberAttributes.Family | MemberAttributes.Override; createNewElementMethod.ReturnType = GlobalReference(typeof(System.Configuration.ConfigurationElement)); createNewElementMethod.Name = "CreateNewElement"; createNewElementMethod.Statements.Add( new CodeMethodReturnStatement(new CodeObjectCreateExpression(collectionItemType)) ); createNewElementMethod.EndDirectives.Add(EndRegion()); if ((collectionElement.CodeGenOptions & ConfigurationElementCollectionCodeGenOptions.Indexer) == ConfigurationElementCollectionCodeGenOptions.Indexer) { // Add indexer for location CodeMemberProperty locationIndexerProperty = new CodeMemberProperty(); elementClass.Members.Add(locationIndexerProperty); locationIndexerProperty.StartDirectives.Add(Region("Indexer")); locationIndexerProperty.Comments.Add(DocComment("<summary>")); locationIndexerProperty.Comments.Add(DocComment(string.Format("Gets the <see cref=\"{0}\"/> at the specified index.", collectionItemTypeReference))); locationIndexerProperty.Comments.Add(DocComment("</summary>")); locationIndexerProperty.Comments.Add(DocComment(string.Format("<param name=\"index\">The index of the <see cref=\"{0}\"/> to retrieve.</param>", collectionItemTypeReference))); locationIndexerProperty.CustomAttributes.Add(_generatedCodeAttribute); locationIndexerProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Overloaded; locationIndexerProperty.Type = GlobalSelfReference(collectionElement.ItemType.FullName); locationIndexerProperty.Name = "Item"; locationIndexerProperty.Parameters.Add(new CodeParameterDeclarationExpression(_int, "index")); locationIndexerProperty.HasGet = true; locationIndexerProperty.GetStatements.Add( new CodeMethodReturnStatement( new CodeCastExpression( collectionItemType, new CodeMethodInvokeExpression( _base, "BaseGet", new CodeArgumentReferenceExpression("index") ) ) ) ); // Add GetItemByKey method CodeMemberProperty keyIndexerProperty = new CodeMemberProperty(); elementClass.Members.Add(keyIndexerProperty); keyIndexerProperty.Comments.Add(DocComment("<summary>")); keyIndexerProperty.Comments.Add(DocComment(string.Format("Gets the <see cref=\"{0}\"/> with the specified key.", collectionItemTypeReference))); keyIndexerProperty.Comments.Add(DocComment("</summary>")); keyIndexerProperty.Comments.Add(DocComment(string.Format("<param name=\"{0}\">The key of the <see cref=\"{1}\"/> to retrieve.</param>", keyProperty.XmlName, collectionItemTypeReference))); keyIndexerProperty.CustomAttributes.Add(_generatedCodeAttribute); keyIndexerProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Overloaded; keyIndexerProperty.Type = collectionItemType; keyIndexerProperty.Name = "Item"; keyIndexerProperty.Parameters.Add(new CodeParameterDeclarationExpression(_object, keyProperty.XmlName)); keyIndexerProperty.GetStatements.Add( new CodeMethodReturnStatement( new CodeCastExpression( collectionItemType, new CodeMethodInvokeExpression( _base, "BaseGet", new CodeArgumentReferenceExpression(keyProperty.XmlName) ) ) ) ); keyIndexerProperty.EndDirectives.Add(EndRegion()); } if ((collectionElement.CodeGenOptions & ConfigurationElementCollectionCodeGenOptions.AddMethod) == ConfigurationElementCollectionCodeGenOptions.AddMethod) { // Add Add method CodeMemberMethod addMethod = new CodeMemberMethod(); elementClass.Members.Add(addMethod); addMethod.StartDirectives.Add(Region("Add")); addMethod.Comments.Add(DocComment("<summary>")); addMethod.Comments.Add(DocComment(string.Format("Adds the specified <see cref=\"{0}\"/> to the <see cref=\"{1}\"/>.", collectionItemTypeReference, configurationElementCollectionTypeReference))); addMethod.Comments.Add(DocComment("</summary>")); addMethod.Comments.Add(DocComment(string.Format("<param name=\"{0}\">The <see cref=\"{1}\"/> to add.</param>", collectionElement.XmlItemName, collectionItemTypeReference))); addMethod.CustomAttributes.Add(_generatedCodeAttribute); addMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; addMethod.ReturnType = _void; addMethod.Name = "Add"; addMethod.Parameters.Add(new CodeParameterDeclarationExpression(GlobalSelfReference(collectionElement.ItemType.FullName), collectionElement.XmlItemName)); addMethod.Statements.Add( new CodeMethodInvokeExpression( _base, "BaseAdd", new CodeArgumentReferenceExpression(collectionElement.XmlItemName) ) ); addMethod.EndDirectives.Add(EndRegion()); } if ((collectionElement.CodeGenOptions & ConfigurationElementCollectionCodeGenOptions.RemoveMethod) == ConfigurationElementCollectionCodeGenOptions.RemoveMethod) { // Add Remove method CodeMemberMethod removeMethod = new CodeMemberMethod(); elementClass.Members.Add(removeMethod); removeMethod.StartDirectives.Add(Region("Remove")); removeMethod.Comments.Add(DocComment("<summary>")); removeMethod.Comments.Add(DocComment(string.Format("Removes the specified <see cref=\"{0}\"/> from the <see cref=\"{1}\"/>.", collectionItemTypeReference, configurationElementCollectionTypeReference))); removeMethod.Comments.Add(DocComment("</summary>")); removeMethod.Comments.Add(DocComment(string.Format("<param name=\"{0}\">The <see cref=\"{1}\"/> to remove.</param>", collectionElement.XmlItemName, collectionItemTypeReference))); removeMethod.CustomAttributes.Add(_generatedCodeAttribute); removeMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; removeMethod.ReturnType = _void; removeMethod.Name = "Remove"; removeMethod.Parameters.Add(new CodeParameterDeclarationExpression(collectionItemType, collectionElement.XmlItemName)); removeMethod.Statements.Add( new CodeMethodInvokeExpression( _base, "BaseRemove", new CodeMethodInvokeExpression( _this, "GetElementKey", new CodeArgumentReferenceExpression(collectionElement.XmlItemName) ) ) ); removeMethod.EndDirectives.Add(EndRegion()); } if ((collectionElement.CodeGenOptions & ConfigurationElementCollectionCodeGenOptions.GetItemMethods) == ConfigurationElementCollectionCodeGenOptions.GetItemMethods) { // Add GetItemAt method CodeMemberMethod getItemAtMethod = new CodeMemberMethod(); elementClass.Members.Add(getItemAtMethod); getItemAtMethod.StartDirectives.Add(Region("GetItem")); getItemAtMethod.Comments.Add(DocComment("<summary>")); getItemAtMethod.Comments.Add(DocComment(string.Format("Gets the <see cref=\"{0}\"/> at the specified index.", collectionItemTypeReference))); getItemAtMethod.Comments.Add(DocComment("</summary>")); getItemAtMethod.Comments.Add(DocComment(string.Format("<param name=\"index\">The index of the <see cref=\"{0}\"/> to retrieve.</param>", collectionItemTypeReference))); getItemAtMethod.CustomAttributes.Add(_generatedCodeAttribute); getItemAtMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; getItemAtMethod.ReturnType = collectionItemType; getItemAtMethod.Name = "GetItemAt"; getItemAtMethod.Parameters.Add(new CodeParameterDeclarationExpression(_int, "index")); getItemAtMethod.Statements.Add( new CodeMethodReturnStatement( new CodeCastExpression( collectionItemType, new CodeMethodInvokeExpression( _base, "BaseGet", new CodeArgumentReferenceExpression("index") ) ) ) ); // Add GetItemByKey method CodeMemberMethod getItemByKeyMethod = new CodeMemberMethod(); elementClass.Members.Add(getItemByKeyMethod); getItemByKeyMethod.Comments.Add(DocComment("<summary>")); getItemByKeyMethod.Comments.Add(DocComment(string.Format("Gets the <see cref=\"{0}\"/> with the specified key.", collectionItemTypeReference))); getItemByKeyMethod.Comments.Add(DocComment("</summary>")); getItemByKeyMethod.Comments.Add(DocComment(string.Format("<param name=\"{0}\">The key of the <see cref=\"{1}\"/> to retrieve.</param>", keyProperty.XmlName, collectionItemTypeReference))); getItemByKeyMethod.CustomAttributes.Add(_generatedCodeAttribute); getItemByKeyMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; getItemByKeyMethod.ReturnType = collectionItemType; getItemByKeyMethod.Name = "GetItemByKey"; getItemByKeyMethod.Parameters.Add(new CodeParameterDeclarationExpression(GlobalReference(keyProperty.TypeName), keyProperty.XmlName)); getItemByKeyMethod.Statements.Add( new CodeMethodReturnStatement( new CodeCastExpression( collectionItemType, new CodeMethodInvokeExpression( _base, "BaseGet", new CodeCastExpression( _object, new CodeArgumentReferenceExpression(keyProperty.XmlName) ) ) ) ) ); getItemByKeyMethod.EndDirectives.Add(EndRegion()); } }