namespace System.Xml.Serialization
{
+ [AttributeUsage (AttributeTargets.Class, AllowMultiple = false)]
+ internal class XmlTypeConvertorAttribute : Attribute
+ {
+ /*
+ * Bug #12571:
+ *
+ * System.Xml.Linq.XElement should be deserializable from an XmlElement.
+ *
+ * Types can now register a custom deserializer by adding this custom attribute.
+ * Method is the name of a private 'static method (static object)' method that will
+ * be invoked to construct an instance of the object.
+ *
+ */
+ public string Method {
+ get;
+ private set;
+ }
+
+ public XmlTypeConvertorAttribute (string method)
+ {
+ Method = method;
+ }
+ }
+
internal class TypeData
{
Type type;
TypeData listTypeData;
TypeData mappedType;
XmlSchemaPatternFacet facet;
+ MethodInfo typeConvertor;
bool hasPublicConstructor = true;
bool nullableOverride;
if (sType == SchemaTypes.Array || sType == SchemaTypes.Class) {
hasPublicConstructor = !type.IsInterface && (type.IsArray || type.GetConstructor (Type.EmptyTypes) != null || type.IsAbstract || type.IsValueType);
}
+
+ LookupTypeConvertor ();
}
internal TypeData (string typeName, string fullTypeName, string xmlType, SchemaTypes schemaType, TypeData listItemTypeData)
this.hasPublicConstructor = true;
}
+ void LookupTypeConvertor ()
+ {
+#if NET_4_5
+ // We only need this for System.Xml.Linq.
+ var convertor = type.GetCustomAttribute<XmlTypeConvertorAttribute> ();
+ if (convertor != null)
+ typeConvertor = type.GetMethod (convertor.Method, BindingFlags.Static | BindingFlags.NonPublic);
+#endif
+ }
+
+ internal void ConvertForAssignment (ref object value)
+ {
+ // Has this object registered a custom type converter?
+ if (typeConvertor != null)
+ value = typeConvertor.Invoke (null, new object[] { value });
+ }
+
public string TypeName
{
get {
};
#if NET_2_0
- private Type GetGenericListItemType (Type type)
+ internal static Type GetGenericListItemType (Type type)
{
- if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof (ICollection<>))
- return type.GetGenericArguments () [0];
+ if (type.IsGenericType && typeof(IEnumerable).IsAssignableFrom(type.GetGenericTypeDefinition ())) {
+ Type [] gatypes = type.GetGenericArguments ();
+ if (type.GetMethod ("Add", gatypes) != null)
+ return gatypes [0];
+ }
Type t = null;
foreach (Type i in type.GetInterfaces ())
if ((t = GetGenericListItemType (i)) != null)