Generating an Xml Serialization Assembly as Part of My Build

Generating an Xml Serialization assembly as part of my build

This is how I managed to do it by modifying the MSBUILD script in my .CSPROJ file:

First, open your .CSPROJ file as a file rather than as a project. Scroll to the bottom of the file until you find this commented out code, just before the close of the Project tag:

<!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->

Now we just insert our own AfterBuild target to delete any existing XmlSerializer and SGen our own, like so:

<Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)" Outputs="$(OutputPath)$(_SGenDllName)">
<!-- Delete the file because I can't figure out how to force the SGen task. -->
<Delete
Files="$(TargetDir)$(TargetName).XmlSerializers.dll"
ContinueOnError="true" />
<SGen
BuildAssemblyName="$(TargetFileName)"
BuildAssemblyPath="$(OutputPath)"
References="@(ReferencePath)"
ShouldGenerateSerializer="true"
UseProxyTypes="false"
KeyContainer="$(KeyContainerName)"
KeyFile="$(KeyOriginatorFile)"
DelaySign="$(DelaySign)"
ToolPath="$(TargetFrameworkSDKToolsDirectory)"
Platform="$(Platform)">
<Output
TaskParameter="SerializationAssembly"
ItemName="SerializationAssembly" />
</SGen>
</Target>

That works for me.

Automatically Create XmlSerializer assembly

Generating an Xml Serialization assembly as part of my build

http://social.msdn.microsoft.com/forums/en-US/sqlnetfx/thread/d252d732-5e5b-480b-8280-285636da7db1/

When to change the Generate Serialization Assembly value?

In order to serialize classes/structs, serialization assemblies need to be generated. This can happen at compiletime or runtime. Sgen.exe is used to generate serialization assemblies at compiletime; Visual Studio can optionally automate this process, as you have discovered.

  • Off: Default for Debug configurations (thanks, @Alexandru Lache). Do not generate serialization assemblies at compiletime. Serialization assemblies will be generated each time the application runs, according to MSDN:

    When the XML Serializer Generator is not used, a XmlSerializer generates serialization code and a serialization assembly for each type every time an application is run. To improve the performance of XML serialization startup, use the Sgen.exe tool to generate those assemblies the assemblies in advance. These assemblies can then be deployed with the application.

  • On: Use Sgen.exe to generate a serialization assembly at compiletime. This saves startup time, but increases deployment size.
  • Auto: Default for Release configurations. Officially, only generates assembly if XmlSerializer is used in your code, per MSDN (thanks, @L-Three). In my tests, this didn't always work, so I recommend explicitly setting it to On if you are using XmlSerializer.

So, my answer would be this: if you are concerned about startup time, and you use the Serializable attribute even once, set the option to On. If you are more concerned about deployment size, change it to Off. I never leave it on Auto anymore, because I don't trust it. Like I said, it seems to be the same as Off, but I wouldn't count on it.

Edit: I'm definitely having some trouble differentiating between Off and Auto. The difference isn't clearly defined anywhere. I'd stick with On if you use the Serializable attribute at all, and Off if you don't. I wouldn't take deployment size or startup time into account. I just seem to run into fewer serialization-related bugs if I stick to that rule.

Update:

After a review of the sources mentioned, I believe "startup" refers to the first time an XmlSerializer is used on any given type, not initial application launch. I can't be sure; it's a bit ambiguous.

What is the benefit of turning Generate Serialization Assemblies off?

Only problems you might be facing are with build tools - such as msbuild, because if you use sgen from x32 SDK on assembly that is explicitly x64 it will raise a build-time error (you can easily overcome this by setting correct SGenToolPath path to msbuild or target MSIL instead). IMHO it is better to deal with build time issues and have quicker startup time.

Does setting Generate serialization assembly to off force generation every time the code is touched or just once?

It will only affect startup performance for an application.

https://docs.microsoft.com/en-us/dotnet/standard/serialization/xml-serializer-generator-tool-sgen-exe

When the XML Serializer Generator is not used, a XmlSerializer generates serialization code and a serialization assembly for each type every time an application is run. To improve the performance of XML serialization startup, use the Sgen.exe tool to generate those assemblies in advance. These assemblies can then be deployed with the application.

The XML Serializer Generator can also improve the performance of clients that use XML Web service proxies to communicate with servers because the serialization process will not incur a performance hit when the type is loaded the first time.

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

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.

Why won't Visual Studio 2005 generate an Xml Serialization assembly?

It turns out that Dev Studio only honors this setting for Web Services.

For non-web services you can get this to work by adding an AfterBuild target to your project file:

  <Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)"  Outputs="$(OutputPath)$(_SGenDllName)">         
<SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(OutputPath)" References="@(ReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="false" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="$(SGenToolPath)">
<Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
</SGen>
</Target>

See also:

  • SGen MSBuild Task
  • AfterBuild Event


Related Topics



Leave a reply



Submit