6

我正在使用 ILMerge 合并几个 .NET 程序集,包括一些第 3 方程序集。自从这样做以来,我遇到了几个错误,这些错误都归结为类型定义与定义它们的程序集相关联的事实。

一个简单的示例是我的 App.config 中的 log4net 配置部分定义。它使用 type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" 这将不起作用,因为 log4net 程序集一旦合并到我的合并程序集中就不存在了。不过没什么大不了的,我将程序集名称更改为我的合并程序集,它工作正常。

一个稍微复杂一点的例子是二进制序列化类型。我的系统使用二进制序列化在进程之间发送某些对象。所有可序列化对象都在所有其他项目引用的公共程序集中定义。我正在使用默认的二进制序列化,但是在反序列化对象时它开始失败,并出现错误,指出它找不到序列化对象的合并程序集。同样,没什么大不了的,我实现了一个自定义 SerializationBinder,它在任何加载的程序集中查找类型,而不仅仅是给定的。

当序列化类型引用其他可序列化类型时,前面的示例变得更加复杂。我继续遇到越来越多的问题,这些问题越来越难以处理。

我想在这里说明的一点是 .NET 类型系统和 ILMerge 似乎不能很好地协同工作。有没有人对他们如何解决这个问题有任何经验?是否可以告诉 .NET 运行时我不在乎该类型说它应该在哪个程序集中,只要在任何地方寻找它?

注意:请不要回复询问我为什么要合并程序集,这不是这个问题的重点。

4

3 回答 3

4

是的,这个问题有一个解决方案:构建模块而不是程序集!

.net 的编译器有一个选项(C# 和 VB 的 /target:module),它构建模块而不是程序集。然后可以将多个模块传递给编译器并用于构建最终程序集。

当然,这一切都假设您已经获得了那些第 3 方集会的来源。如果你不能得到那个,也许可以从第 3 方采购一个 .netmodule 版本的第 3 方程序集?

如果这不起作用,你还有最后一个选择。显然,您已经将第 3 方程序集分解为 IL。从该 IL 文件中删除程序集信息并使用“ilasm /dll”构建一个 .net 模块,您现在应该可以像使用任何其他 .net 模块一样使用它!

通过使用模块而不是程序集,您不应该再遇到任何基于程序集的问题。

诚然,我们通过不再使用 ILMerge 解决了您的 ILMerge 问题,但这真的不是最好的解决方案吗?

希望它对你有用,这里有一些方便的链接:
.netmodule 而不是
用 .netmodules 组装 ILASM

(在这里我在想我在 .netmodules 方面的经验对任何人都没有用处!)

于 2010-03-12T20:12:09.697 回答
0

提出问题几年后,我遇到了同样的问题并找到了解决方案。您可以添加[assembly: log4net.Config.XmlConfigurator(ConfigFile = "logging.config", Watch = true)]到 AssemblyInfo.cs 文件中,这将在合并 log4net 程序集时起作用。

于 2018-01-23T11:35:45.767 回答
-2

欢迎来到代码中的字符串和(物理位置)字符串的危险..

所有这类工具都有类似的问题,它们最好是聪明的,因为许多运行时特性(如绑定和序列化)的开发人员和设计人员并没有真正设想到它,但他们确实将 ILMerge 推为“智能”工具。它非常聪明,甚至无法修剪类型。

请注意,版本控制也在这里发挥作用,配置、.* 和他们眼中的星星,以及来自 Redmond 的版本独立性也无济于事。

您肯定会不断遇到第三方位的麻烦。相信我,我知道你需要合并,因为一些可悲的少数类型可能需要很长时间才能让 MS JIT 用于大型应用程序(不,我不希望 NGEN 或优化的 3.5SP1 加载比以前更慢由于 System.Core 或天堂禁止的 WPF 膨胀)。

最好的选择,恕我直言,至少在大规模上,是获得一个体面的商业工具来扫描和处理这个问题(即,从现有的痛苦和混淆体验中)。从长远来看,如果您没有源代码,您最终可能会检测现有的 IL 代码。

[然后有一个 INotifyPropertyChanged 字符串发明,从而解决了全球变暖问题 - 由 Casio-Calc Inventors 设计]

于 2009-11-05T18:27:35.180 回答