使用 Sgen 和 ILMerge 预生成 XmlSerializer。数组的问题
我广泛使用 XmlSerializer,而不是允许 .NET 在运行时生成必要的序列化程序集,我希望提前生成这些程序集并将它们与我的应用程序捆绑在一起。我能够使用 Sgen 在构建时生成这些程序集。此外,我必须为要序列化的每个数组类型单独运行 Sgen(使用 sgen /t:Foo[])。最后,我使用 ILMerge 将数组类型序列化类合并到 Foo.XmlSerializers.dll 程序集中。我已经使用 ildasm 验证了 Foo.XmlSErializers.dll 实际上包含所有合并的类。
在运行时,.NET 成功从 Foo.XmlSerializers.dll 加载 FooSerializer,而无需调用 csc 并生成临时程序集。但是,.NET 无法从同一 dll 加载 ArrayOfFooSerializer,并且实际上调用了 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[]'。
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[]'.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的问题实际上可能是由于您运行了 ILMerge。您生成的序列化程序集会跟踪生成它的程序集的准确版本,如果有任何差异(即使仅在代码中,而不是在界面中),则会说它已过期。事实证明,ILMerge 更改了程序集 ID,这可能是导致此问题的原因。 有关该问题的详细信息,请参阅此帖子 。
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.
您可以尝试查看 Mono 中的 sgen,它允许一次生成多种类型的序列化程序集。
You could try looking at sgen from Mono, it allows generating serialization assembly for multiple types at once.