private CompositeAnnotation DeserializeCompositeAnnotation(Type annotationType, StructuralAnnotation annotation) { var composite = (CompositeAnnotation)Activator.CreateInstance(annotationType, true); foreach (var prop in composite.GetType().GetAllInstanceProperties()) { if (prop.CanWrite) { var element = annotation.Content.Element(EdmConstants.TaupoAnnotationsNamespace + prop.Name); if (element != null) { Type targetType = prop.PropertyType; // if it's Nullable<T>, extract T targetType = Nullable.GetUnderlyingType(targetType) ?? targetType; object typedValue; string stringValue = element.Value; if (targetType == typeof(string)) { typedValue = stringValue; } else if (targetType.IsEnum()) { typedValue = Enum.Parse(targetType, stringValue, false); } else if (targetType == typeof(Guid)) { typedValue = new Guid(stringValue); } else { ExceptionUtilities.Assert(targetType.IsPrimitive() || targetType == typeof(decimal), "Non-primitive types are not supported."); typedValue = Convert.ChangeType(element.Value, targetType, CultureInfo.InvariantCulture); } prop.SetValue(composite, typedValue, null); } } } return composite; }
private Annotation ConvertSingleAnnotation(StructuralAnnotation annotation) { if (annotation.Content == null) { return annotation; } if (annotation.Content.Name.Namespace != EdmConstants.TaupoAnnotationsNamespace) { return annotation; } Type annotationType = this.FindAnnotationType(annotation.Content.Name); if (annotationType == null) { return annotation; } if (typeof(ICustomAnnotationSerializer).IsAssignableFrom(annotationType)) { // since this interface is implemented, we also expect a constructor // which takes an XElement to be there, so let's just invoke it // on our XElement return (Annotation)Activator.CreateInstance(annotationType, annotation.Content); } if (typeof(CompositeAnnotation).IsAssignableFrom(annotationType)) { return this.DeserializeCompositeAnnotation(annotationType, annotation); } // any other annotation type - just return it return annotation; }