Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pre-generating XmlSerializers using Sgen and ILMerge. Trouble with arrays

I use XmlSerializer extensively and rather than allowing .NET to generate the necessary serialization assemblies at runtime, I'd like to generate these assemblies ahead of time and bundle them with my application. I am able to use Sgen to generate these assemblies at build time. Additionally, I must run Sgen separately for each array type that I will serialize (using sgen /t:Foo[]). Finally, I use ILMerge to merge the array type serialization classes into the Foo.XmlSerializers.dll assembly. I have verified with ildasm that Foo.XmlSErializers.dll does in fact contain all of the merged classes.

At runtime, .NET successfully loads FooSerializer from Foo.XmlSerializers.dll without invoking csc and generating a temporary assembly. However, .NET fails to load ArrayOfFooSerializer from the same dll, and does in fact invoke csc.

How can I successfully pre-generate serialization types for arrays?

Consider the following 2 assemblies and their simplified contents:

Assembly: MyApp.exe

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

Assembly: Foo.dll

public class Foo
{

}

Further Info:

The following app.config causes XmlSerialization related events to be added to the Event Log

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

I see no events for the Foo type. I see the following message for Foo[]:

Pre-generated serializer 'Foo.XmlSerializers' has expired. You need to re-generate serializer for 'Foo[]'.

like image 879
anthony Avatar asked Jan 23 '23 22:01

anthony


1 Answers

Your problem may actually be due to the fact that you ran ILMerge. The serialization assembly you generate tracks the exact version of the assembly it was generated from, and will say it has expired if there is any difference (even if only in the code, and not the interface). As it turns out, ILMerge changes that Assembly ID, which could be causing this. See this post for more information about the problem.

like image 187
Nick Avatar answered Feb 12 '23 04:02

Nick