合并程序集中的.NET类型定义(ILMerge)

时间:2009-11-05 18:04:28

标签: .net types ilmerge

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

一个简单的例子是我的App.config中的log4net配置部分定义。它使用type =“log4net.Config.Log4NetConfigurationSectionHandler,log4net”,由于log4net程序集合并到我的合并程序集后不存在,因此无效。不过没什么大不了的,我将程序集名称更改为我的合并程序集,它运行正常。

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

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

我试图在这里得到的一点是.NET类型系统和ILMerge似乎并不能很好地协同工作。有没有人对他们如何解决这个问题有任何经验?是否有可能告诉.NET运行时我不关心它应该是什么类型的程序集,只需在任何地方查找它?

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

3 个答案:

答案 0 :(得分:4)

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

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

当然,这一切都假设您已获得第三方组件的来源。如果你不能得到它,也许第三方组件的.netmodule版本可以从第三方获得?

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

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

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

希望它适合你,这里有一些方便的联系:
.netmodule instead of assembly
ILASM with .netmodules

(在这里我认为我对.netmodules的经验永远不会对任何人有用!)

答案 1 :(得分:0)

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

答案 2 :(得分:-2)

欢迎使用代码中的字符串和(物理位置)字符串的危险。

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

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

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

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

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