public void SerializationTest()
        {
            // Arrange.
            const string DisplayName = "Test Type";
            const string Name = "TestType";
            const string ElementTypeName = "ElementType";
            const WebServiceTypeCode TypeCode = WebServiceTypeCode.String;
            const string DerivedTypeName = "TestDerivedType";
            const string FieldName = "TestField";
            const string FieldType = "TestFieldType";

            var service = new WebServiceClientDescription();
            var type = new WebServiceTypeDescription(service)
                           {
                               DisplayName = DisplayName,
                               Name = Name,
                               ElementTypeName = ElementTypeName,
                               IsSimple = true,
                               IsArray = true,
                               IsAbstract = true,
                               IsEnum = true,
                               IsNullable = true,
                               TypeCode = TypeCode
                           };

            type.AssignableTypes.Add(new WebServiceTypeReference { TypeName = DerivedTypeName });
            type.Fields.Add(new WebServiceTypeFieldDescription(type) { Name = FieldName, TypeName = FieldType });

            // Act.
            var element = type.GetXElement();
            var newType = WebServiceTypeDescription.CreateTypeDescription(service, element);

            // Assert.
            Assert.AreEqual(DisplayName, newType.DisplayName);
            Assert.AreEqual(Name, newType.Name);
            Assert.AreEqual(ElementTypeName, newType.ElementTypeName);
            Assert.IsTrue(newType.IsSimple);
            Assert.IsTrue(newType.IsArray);
            Assert.IsTrue(newType.IsAbstract);
            Assert.IsTrue(newType.IsEnum);
            Assert.IsTrue(newType.IsNullable);
            Assert.AreEqual(TypeCode, newType.TypeCode);
            
            Assert.AreEqual(1, newType.AssignableTypes.Count);
            Assert.AreEqual(DerivedTypeName, newType.AssignableTypes.ElementAt(0).TypeName);

            Assert.AreEqual(1, newType.Fields.Count);
            Assert.AreEqual(FieldName, newType.Fields.ElementAt(0).Name);
            Assert.AreEqual(FieldType, newType.Fields.ElementAt(0).TypeName);
        }
        public void IsAssignableFromTest()
        {
            // Arrange.
            var service = new WebServiceClientDescription();
            var type1 = new WebServiceTypeDescription(service) { Name = "Type1" };
            var derived1 = new WebServiceTypeDescription(service) { Name = "Derived1" };
            var derived2 = new WebServiceTypeDescription(service) { Name = "Derived2" };
            var type2 = new WebServiceTypeDescription(service) { Name = "Type2" };

            type1.AssignableTypes.Add(new WebServiceTypeReference { TypeName = derived1.Name });
            type1.AssignableTypes.Add(new WebServiceTypeReference { TypeName = derived2.Name });

            // Act / Assert.
            Assert.IsTrue(type1.IsAssignableFrom(type1));
            Assert.IsTrue(type1.IsAssignableFrom(derived1));
            Assert.IsTrue(type1.IsAssignableFrom(derived2));
            Assert.IsFalse(type1.IsAssignableFrom(type2));
        }
        public void GetAssignableTypesForTypeTest()
        {
            // Arrange.
            var serviceDescription = new WebServiceClientDescription();
            var type1 = new WebServiceTypeDescription(serviceDescription) { Name = "Type1" };
            var type2 = new WebServiceTypeDescription(serviceDescription) { Name = "Type2" };
            var type3 = new WebServiceTypeDescription(serviceDescription) { Name = "Type3", IsAbstract = true };

            type1.AssignableTypes.Add(new WebServiceTypeReference { TypeName = type2.Name });
            type1.AssignableTypes.Add(new WebServiceTypeReference { TypeName = type3.Name });

            serviceDescription.TypeDescriptions.Add(type1);
            serviceDescription.TypeDescriptions.Add(type2);
            serviceDescription.TypeDescriptions.Add(type3);

            // Act.
            var assignableTypes = serviceDescription.GetAssignableTypesForType(type1);

            // Assert.
            Assert.AreEqual(2, assignableTypes.Count);
            Assert.IsTrue(assignableTypes.Contains(type1));
            Assert.IsTrue(assignableTypes.Contains(type2));
        }
        public void FindTypeByNameTest()
        {
            // Arrange.
            var serviceDescription = new WebServiceClientDescription();
            var type1 = new WebServiceTypeDescription(serviceDescription) { Name = "Type1" };
            var type2 = new WebServiceTypeDescription(serviceDescription) { Name = "Type2" };
            
            serviceDescription.TypeDescriptions.Add(type1);
            serviceDescription.TypeDescriptions.Add(type2);

            // Act / Assert.
            Assert.AreSame(type1, serviceDescription.FindTypeByName("Type1"));
            Assert.AreSame(type2, serviceDescription.FindTypeByName("Type2"));
            Assert.IsNull(serviceDescription.FindTypeByName("Type3"));
        }
 /// <summary>
 /// Gets the type field description.
 /// </summary>
 /// <param name="declaringType">Type of the declaring.</param>
 /// <param name="field">The field.</param>
 /// <returns>WebServiceTypeFieldDescription.</returns>
 private static WebServiceTypeFieldDescription GetTypeFieldDescription(WebServiceTypeDescription declaringType, FieldInfo field)
 {
     return new WebServiceTypeFieldDescription(declaringType) { Name = field.Name, TypeName = field.FieldType.GetAssemblyQualifiedName() };
 }
        /// <summary>
        /// Gets the type description.
        /// </summary>
        /// <param name="declaringService">The declaring service.</param>
        /// <param name="type">The type.</param>
        /// <returns>WebServiceTypeDescription.</returns>
        private WebServiceTypeDescription GetTypeDescription(WebServiceClientDescription declaringService, Type type)
        {
            var underlyingType = Nullable.GetUnderlyingType(type);
            var typeDescription = new WebServiceTypeDescription(declaringService)
                                      {
                                          TypeCode = WebServiceTypeDescription.GetTypeCode(underlyingType ?? type),
                                          Name = type.GetAssemblyQualifiedName(),
                                          DisplayName = GetDisplayName(underlyingType ?? type),
                                          IsAbstract = type.IsAbstract,
                                          IsArray = type.IsArray,
                                          IsEnum = (underlyingType ?? type).IsEnum,
                                          IsSimple = IsSimpleType(underlyingType ?? type),
                                          IsNullable = IsNullableType(type)
                                      };

            if (type.IsArray)
                typeDescription.ElementTypeName = type.GetElementType().GetAssemblyQualifiedName();

            if (type.Assembly == _proxyAssembly && !type.IsArray && !IsSimpleType(type))
                typeDescription.Fields.AddRange(
                    type.GetFields(BindingFlags.Instance | BindingFlags.Public).Select(f => GetTypeFieldDescription(typeDescription, f)));

            typeDescription.AssignableTypes.AddRange(GetIncludedTypes(type).Where(type.IsAssignableFrom).Select(GetTypeReference));

            return typeDescription;
        }
        /// <summary>
        /// Creates the type description.
        /// </summary>
        /// <param name="declaringService">The declaring service.</param>
        /// <param name="element">The element.</param>
        /// <returns>The <see cref="WebServiceTypeDescription"/>.</returns>
        public static WebServiceTypeDescription CreateTypeDescription(WebServiceClientDescription declaringService, XElement element)
        {
            ParseHelper.CheckRequiredElement(element, CnType);

            var type = new WebServiceTypeDescription(declaringService)
                           {
                               TypeCode =
                                   (WebServiceTypeCode)
                                   Enum.Parse(
                                       typeof(WebServiceTypeCode),
                                       ParseHelper.ReadRequiredAttribute(element, CnTypeCode),
                                       true),
                               Name = ParseHelper.ReadRequiredAttribute(element, CnName),
                               DisplayName = ParseHelper.ReadRequiredAttribute(element, CnDisplayName),
                               IsSimple =
                                   bool.Parse(ParseHelper.ReadOptionalAttribute(element, CnIsSimple, bool.FalseString)),
                               IsArray =
                                   bool.Parse(ParseHelper.ReadOptionalAttribute(element, CnIsArray, bool.FalseString)),
                               IsAbstract =
                                   bool.Parse(ParseHelper.ReadOptionalAttribute(element, CnIsAbstract, bool.FalseString)),
                               IsEnum = bool.Parse(ParseHelper.ReadOptionalAttribute(element, CnIsEnum, bool.FalseString)),
                               IsNullable =
                                   bool.Parse(ParseHelper.ReadOptionalAttribute(element, CnIsNullable, bool.FalseString))
                           };

            if (element.Attribute(CnElementTypeName) != null)
                type.ElementTypeName = ParseHelper.ReadOptionalAttribute(element, CnElementTypeName);

            var fieldsElement = element.Element(CnFields);

            if (fieldsElement != null)
            {
                type.Fields.AddRange(
                    fieldsElement.Elements(WebServiceTypeFieldDescription.CnField).Select(f => WebServiceTypeFieldDescription.CreateFieldDescription(type, f)));
            }

            var includedTypesElement = element.Element(CnAssignableTypes);

            if (includedTypesElement != null)
            {
                type.AssignableTypes.AddRange(includedTypesElement.Elements(WebServiceTypeReference.CN_TypeRef).Select(WebServiceTypeReference.CreateTypeReference));
            }

            return type;
        }
 /// <summary>
 /// Creates a new web method call header.
 /// </summary>
 /// <param name="name">The header name.</param>
 /// <param name="type">The header type.</param>
 /// <returns>Returns a <see cref="IWebMethodCallParameter" />.</returns>
 public IWebMethodCallParameter CreateHeader(string name, WebServiceTypeDescription type)
 {
     return WebMethodCallParameterEdit.CreateHeader(name, type);
 }
        /// <summary>
        /// Creates a field description.
        /// </summary>
        /// <param name="declaringType">
        /// The declaring type.
        /// </param>
        /// <param name="element">
        /// The element.
        /// </param>
        /// <returns>
        /// The <see cref="WebServiceTypeFieldDescription"/>.
        /// </returns>
        public static WebServiceTypeFieldDescription CreateFieldDescription(WebServiceTypeDescription declaringType, XElement element)
        {
            ParseHelper.CheckRequiredElement(element, CnField);

            return new WebServiceTypeFieldDescription(declaringType)
                       {
                           Name = ParseHelper.ReadRequiredAttribute(element, CnName),
                           TypeName = ParseHelper.ReadRequiredAttribute(element, CnTypeName)
                       };
        }