我有一个库动态链接库与排序算法,解析器,验证器,转换器等充满。动态链接库大约是40Mb(这不是我所知道的很多,但仍然)。现在,我只想引用该DLL的解析器。重点是在不向客户交付40Mb的情况下获得这些解析器。
有没有办法在每次发布构建时,从我的库中获取这些最新的解析器,将它们存储到某种.partialDll文件中,然后只将它们交付给客户?结果就是我把我所有的助手类都放在一个不断增长的大库中,然后客户就可以得到他们订购的东西了。
我想我需要进行大量的思考才能达到这样的效果,对吧?有什么想法吗?
发布于 2015-06-26 19:44:04
让我从引用from MSDN开始
“
”程序集是.NET框架应用程序的构建块;它们形成了部署…的基本单元。
请注意,引用是关于程序集的,而不是关于DLL的。这是有区别的!
尽管大多数.NET程序集只由一个DLL文件组成,但这并不是一个严格的要求:一个程序集实际上可以由多个文件组成;例如,这样的"multi-file assembly"可以由几个DLL组成,这些DLL又称为“网络模块”。(按照惯例,netmodule文件扩展名可能是.netmodule,但它实际上是一个包含netmodule元数据和字节码的.NET。)每个多文件程序集都恰好有一个“主”模块,该模块携带引用所有其他程序集文件的元数据,从而将它们联系在一起形成一个逻辑整体。
虽然程序集必须完全部署(根据上面的引用),但.NET运行时只能加载JIT代码编译和执行实际需要的那些netmodule。
因此,您可以将程序集拆分为几个部分,并让运行时只加载实际需要的部分;但不能对netmodule / DLL文件执行同样的操作。DLL文件只能完整地部署和加载。
还要注意的是,Visual Studio对netmodules的支持在所有实际用途中都是不存在的,因此大多数人不使用它们,这就是为什么您在现实世界中看到的多文件程序集如此之少的原因。
底线是这样的:在实践中,如果您或您的客户只对程序集("DLL")的一部分感兴趣,那么通常更容易将一个大型程序集(即一个大型Visual Studio项目)拆分为几个相互依赖的程序集(几个较小的Visual Studio项目)。
发布于 2015-06-26 20:21:49
一般来说,不,没有办法做到这一点。一旦你将“一切”打包到一个模块中并编译它,你就不能在以后将该模块拆分成更小的模块。(好吧,好吧,你可以分析字节码并重写程序集,请参阅本文的结尾)。
对我来说,你的零假设似乎是错误的。你不需要使用“一个巨大的库来保存你所有的助手类”,真的,你不想要,或者你也不想要。如果你没有这样的感觉,我向你保证,随着时间的推移,也许几年后,你会讨厌这种一刀切的方法。
这正是你想要摆脱的,这就是为什么.Net和许多其他语言/环境支持“库”或“模块”的概念,并允许你使用它们中的多个,这也是为什么你在任何地方看到的大多数项目都不是作为“一个巨大的可执行文件”创建的。当你把它放在较小的块中时,重用、分析甚至寻找bug都会变得更容易。
--
然而,如果你坚持,有一些方法(丑陋的)可以达到你想的那样。我假设“巨型动态链接库”是用C#编写的,并由您控制。
首先,有些天真但有效的方法是使用“文件链接”。在VisualStudio中,你可以有一个包含大量文件的项目,并且生成一个BigDLL "all.dll",在它的旁边,你可以创建另一个项目,它将任何文件,但它将包含到第一个项目的文件的链接。使用典型的“添加文件..”选项添加到项目中,请注意,在最后一个“添加”按钮附近有一个向下箭头,它展开为“添加为链接..”。
这将导致文件停留在HugeProject中,但SmallProject也会看到该文件,并且在编译SmallProject时,它也会从该文件中提取代码。
请注意,通过这种方式,您实际上将构建两个独立的模块程序集:一个大模块,一个小模块,并且您的最终产品将需要引用小模块。
这种方式既幼稚又丑陋,就像你手动复制/拆分了一个巨大的项目,但它的一个小优点是,你不需要复制代码文件。
--
中场休息:
#if有条件地关闭一些当前未使用的代码,但是将驱动这些IF的标志设置为cumbersome--
第二种方法是将所有内容都保存在HugeProject中,并让您的应用程序直接引用它,然后在构建和测试所有内容之后,在打包并发送给客户之前-使用某种修剪实用程序来检查代码的哪些部分被引用,并从程序集中删除所有死代码。我不能给你任何这样的工具的名字,但许多模糊都有这样的功能。
它们将遍历您编译的代码,交叉引用所有内容,更改/删除/trash类/方法/属性名称,还可以删除未使用的部分。然后,它们会将损坏的程序集写回磁盘,确保它们相互引用,而不是损坏前的原始程序集。
示例:See a question related to that
示例:See an example of such utility也考虑使用ILMerge以获得更好的结果。
缺点-实用工具可能会留下一些垃圾它无法决定是否使用它,查找/测试/购买它可能需要一些时间和资源,你可能会有一些签名问题,因为剥离的程序集将是一个全新的程序集,等等。同样,如果你只是通过反射调用一些代码,它可能需要你提供一些额外的提示或确保代码“似乎被使用了”(例如:实现"IPlugin“的整个”插件“命名空间,然后你的应用程序在NS中搜索类型并使用Activator.CreateInstance来实例化它们;没有硬链接的用法,trimmer可能会决定将所有插件删除为“未使用”;你需要仔细配置trimmer,否则会感到惊讶)。
也许还可以找到其他一些方法,但说真的,在大多数情况下,你都不想浪费时间,尤其是手动。因此,只需整理代码并将其拆分成小的库,或者开始寻找自动混淆器和修剪器。
https://stackoverflow.com/questions/31071806
复制相似问题