2009-03-24 2 views
8

При построении экземпляров XmlSerializer в .NET сборки для сериализации и десериализации указанного типа генерируются динамически. Это трудоемкий процесс. Средство sgen.exe от Microsoft можно использовать для предварительной компиляции экземпляров XmlSerializer, чтобы использовать их позже, не генерируя их динамически. К сожалению, это невозможно с экземплярами XmlSerializer, которые используют XmlAttributeOverrides.Precompile XmlSerializers с XmlAttributeOverrides

Есть ли способ прекомпилировать эти экземпляры XmlSerializer, чтобы избежать генерации во время выполнения?

+0

У вас есть что-то еще с этим? – Rory

ответ

6

Андреас, это не проблема самого инструмента sgen, это связано с реализацией XmlSerializer.

Когда вы создаете экземпляр XmlSerializer, используя конструктор с одним аргументом типа, он идет и проверяет кеш и ищет предварительно сгенерированные сборки. Но когда вы используете конструктор с XmlAttributeOverrides, XmlSerializer не проверяет кеши и сразу же генерирует временную сборку.

Скорее всего, это из-за весьма радикальных изменений в логике сериализации, которые вы можете достичь с помощью аргумента XmlAttributeOverrides, который не может быть «предусмотрен» во время компиляции такими инструментами, как sgen.

Если вам нужно, чтобы все было скомпилировано, вы [вздох] должны избегать XmlAttributeOverrides. Если это невозможно, попробуйте создать необходимые экземпляры XmlSerializer досрочно, возможно, в фоновом потоке.

Просто для интереса, вот код для конструктора по умолчанию в (кэш проверяет и пытается найти предварительно сгенерированные сборки):

public XmlSerializer(Type type, string defaultNamespace) 
{ 
    this.events = new XmlDeserializationEvents(); 
    if (type == null) 
    { 
     throw new ArgumentNullException("type"); 
    } 
    this.mapping = GetKnownMapping(type, defaultNamespace); 
    if (this.mapping != null) 
    { 
     this.primitiveType = type; 
    } 
    else 
    { 
     this.tempAssembly = cache[defaultNamespace, type]; 
     if (this.tempAssembly == null) 
     { 
      lock (cache) 
      { 
       this.tempAssembly = cache[defaultNamespace, type]; 
       if (this.tempAssembly == null) 
       { 
        XmlSerializerImplementation implementation; 
        Assembly assembly = TempAssembly.LoadGeneratedAssembly(type, defaultNamespace, out implementation); 
        if (assembly == null) 
        { 
         this.mapping = new XmlReflectionImporter(defaultNamespace).ImportTypeMapping(type, null, defaultNamespace); 
         this.tempAssembly = GenerateTempAssembly(this.mapping, type, defaultNamespace); 
        } 
        else 
        { 
         this.mapping = XmlReflectionImporter.GetTopLevelMapping(type, defaultNamespace); 
         this.tempAssembly = new TempAssembly(new XmlMapping[] { this.mapping }, assembly, implementation); 
        } 
       } 
       cache.Add(defaultNamespace, type, this.tempAssembly); 
      } 
     } 
     if (this.mapping == null) 
     { 
      this.mapping = XmlReflectionImporter.GetTopLevelMapping(type, defaultNamespace); 
     } 
    } 
} 

А вот конструктор используется с XmlAttributeOverrides (всегда генерирует сериализации сборка):

public XmlSerializer(Type type, XmlAttributeOverrides overrides, Type[] extraTypes, XmlRootAttribute root, string defaultNamespace, string location, Evidence evidence) 
{ 
    this.events = new XmlDeserializationEvents(); 
    if (type == null) 
    { 
     throw new ArgumentNullException("type"); 
    } 
    XmlReflectionImporter importer = new XmlReflectionImporter(overrides, defaultNamespace); 
    for (int i = 0; i < extraTypes.Length; i++) 
    { 
     importer.IncludeType(extraTypes[i]); 
    } 
    this.mapping = importer.ImportTypeMapping(type, root, defaultNamespace); 
    if (location != null) 
    { 
     this.DemandForUserLocation(); 
    } 
    this.tempAssembly = GenerateTempAssembly(this.mapping, type, defaultNamespace, location, evidence); 
} 
+0

А, я столкнулся с этой проблемой. К сожалению, я не могу использовать динамическое создание сборок сериализации, потому что я не могу запустить csc.exe (я запускаю из защищенного режима Internet Explorer). Какие-либо предложения? Я думаю, что могу захватить файл temp .cs, созданный XmlSerializer, включить в мою сборку и использовать это вместо XmlSerializer напрямую. Звучит грязно, но любые другие идеи? Мой qn здесь: http://stackoverflow.com/questions/7333689/generating-an-xml-serialization-assembly-for-a-custom-xmlserializer – Rory

Смежные вопросы