Предварительная генерация XmlSerializers с использованием Sgen и ILMerge. Проблемы с массивами

Я использую XmlSerializer широко и вместо того, чтобы позволить .NET генерировать необходимые сборки сериализации во время выполнения, я хотел бы генерировать эти сборки раньше времени и связывать их с моим приложением. Я могу использовать Sgen для создания этих сборок во время сборки. Кроме того, я должен запускать Sgen отдельно для каждого типа массива, который я буду сериализовать (используя sgen/t: Foo []). Наконец, я использую ILMerge для объединения классов сериализации типа массива в сборку Foo.XmlSerializers.dll. Я проверил с помощью ildasm, что Foo.XmlSErializers.dll действительно содержит все объединенные классы.

Во время выполнения .NET успешно загружает FooSerializer из Foo.XmlSerializers.dll без вызова csc и создания временной сборки. Однако .NET не загружает ArrayOfFooSerializer из той же DLL и фактически вызывает csc.

Как я могу успешно генерировать типы сериализации для массивов?

Рассмотрим следующие 2 сборки и их упрощенное содержимое:

Сборка: MyApp.exe

public class MyApp
{
    public static int Main(string[] args)
    {
        new XmlSerializer(typeof(Foo));
        new XmlSerializer(typeof(Foo[]));
    }
}

Сборка: Foo.dll

public class Foo
{

}

Дополнительная информация:

Следующий файл app.config вызывает события, связанные с XmlSerialization, для добавления в журнал событий

<configuration>
  <system.diagnostics> 
    <switches> 
      <add name="XmlSerialization.PregenEventLog" value="1" />
      <add name="XmlSerialization.Compilation" value="1" />
    </switches> 
  </system.diagnostics>
</configuration>

Я не вижу событий для типа Foo. Я вижу следующее сообщение для Foo []:

Предварительно сгенерированный сериализатор "Foo.XmlSerializers" истек. Вы необходимо повторно генерировать сериализатор для 'Foo []'.

Ответ 1

Ваша проблема может быть связана с тем, что вы запустили ILMerge. Созданная сериализационная сборка отслеживает точную версию сборки, из которой она была создана, и скажет, что она истекла, если есть какая-либо разница (даже если это только код, а не интерфейс). Как выясняется, ILMerge изменяет идентификатор сборки, который может быть причиной этого. Подробнее см. в этом сообщении.

Ответ 2

Вы можете попробовать посмотреть sgen из Mono, он позволяет сразу создавать сериализацию для нескольких типов.