2011-09-29 13 views
7

me gustaría precargar en C#, el XmlTypeMapping de un conjunto conocido de los tipos de clases de acelerar deserialización XML de ellos al crear la instancia una nueva XmlSerializer como XmlReflectionImporter.ImportTypeMapping (sucediendo durante XmlSerializer contrucción de una clase tipo) es bastante lento y parece ocurrir en cada construcción XmlSerializer.XmlSerializer constructor XmlTypeMapping y XmlRootAttribute argumentos

Además, el contenido xml que estoy analizando me obliga a usar el argumento XmlRootAttribute para establecer el nombre del elemento raíz xml para analizar, ya que no siempre es el mismo. Para lograr eso, puedo usar el constructor XmlSerializer(Type, XmlRootAttribute) para deserializar mi objeto.

Sin embargo, también me gustaría aprovechar el prefetch XmlTypeMapping y no puedo ver ningún constructor XmlSerializer como: XmlSerializer(XmlTypeMapping, XmlRootAttribute) o algo así. ¿Cómo podría lograr eso?

Cualquier ayuda sería muy apreciada! Gracias.

+1

Otra desventaja de ese constructor es que mantendrá un ensamblaje deserializador generado en tiempo de ejecución en la memoria que no se puede liberar – Aphelion

Respuesta

3

La memoria incorporada no se utiliza en ninguno de los constructores que aceptan un XmlRootAttribute. Su mejor opción es utilizar el constructor que acepta un solo parámetro XmlTypeMapping:

public XmlSerializer(XmlTypeMapping xmlTypeMapping) 

Y para envolverlo en su propio constructor que acepta un XmlRootAttribute, y construye la XmlTypeMapping de ella usando XmlReflectionImporter:

public class CachedRootXmlSerializer : XmlSerializer 
{ 
    private static Dictionary<int, XmlTypeMapping> rootMapCache = new Dictionary<int,XmlTypeMapping>(); 

    private static XmlTypeMapping GetXmlTypeMappingFromRoot(Type type, XmlRootAttribute xmlRootAttribute) 
    { 
     XmlTypeMapping result = null; 
     int hash = 17; 

     unchecked 
     { 
      hash = hash * 31 + type.GUID.GetHashCode(); 
      hash = hash * 31 + xmlRootAttribute.GetHashCode(); 
     } 

     lock (rootMapCache) 
     { 
      if (!rootMapCache.ContainsKey(hash)) 
      { 
       XmlReflectionImporter importer = new XmlReflectionImporter(null, null); 
       rootMapCache[hash] = importer.ImportTypeMapping(type, xmlRootAttribute, null); 
      } 
      result = rootMapCache[hash]; 
     } 

     return result; 
    } 

    CachedRootXmlSerializer(Type type, XmlRootAttribute xmlRootAttribute) 
     : base(GetXmlTypeMappingFromRoot(type, xmlRootAttribute)) 
    { 
    } 
} 

¡Disfrútalo!

+1

Gracias, esto es realmente inteligente. :) – dletozeun

Cuestiones relacionadas