我有一个带有排序算法,解析器,验证器,转换器等的库DLL。这个DLL大约是40 Mb(我知道的不多但仍然如此)。现在我想引用该DLL的解析器。重点是在不向客户发送40 Mb的情况下将这些解析器拿出来。
每次我发布版本时,是否有办法从我的库中获取最新的解析器,将它们存储到某种.partialDll
文件中并仅将它们传递给客户?结果是我将所有帮助类保存在一个不断增长的大型库中,而客户只需要他们订购的内容。
我想我需要处理很多反思来实现这样的目标,对吧?有什么想法吗?
答案 0 :(得分:3)
让我先引用引用from MSDN:
"程序集是.NET Framework应用程序的构建块;它们构成了部署的基本单位[...]。"
请注意,引用是关于程序集,而不是关于DLL。这有区别!
虽然大多数.NET程序集只包含一个DLL文件,但这并不是一个严格的要求:程序集实际上可以包含多个文件;例如,这样的"multi-file assembly"可以包含几个DLL,而这些DLL又被称为" netmodules"。 (按照惯例,netmodule可能有.netmodule
个文件扩展名,但它实际上是一个包含.NET元数据和字节码的DLL。)每个多文件程序集都只有一个" main"模块,它携带引用所有其他汇编文件的元数据,因此将它们组合成一个逻辑整体。
虽然必须完全部署程序集(根据上面的引用),但.NET运行时只能加载JIT代码编译和执行实际所需的那些netmodule。
因此,您可以将程序集拆分为多个部分,并使运行时仅加载实际需要的部分;但你不能对netmodule / DLL文件做同样的事情。 只能部署和加载DLL文件。
另请注意,Visual Studio对netmodules的支持对于所有实际目的都不存在,因此大多数人都不使用它们,这就是为什么你在现实世界中看到如此少的多文件程序集的原因
最重要的是:实际上,如果您或您的客户只对装配的一部分感兴趣(" DLL"),那么它通常更容易拆分一个大型程序集(即一个大的Visual Studio项目)到几个相互依赖的程序集(几个较小的Visual Studio项目)。
答案 1 :(得分:0)
总的来说,不,没有办法实现这一目标。一旦你收拾好所有的东西"进入一个模块并编译它,你不能将该模块拆分成较小的模块。 (好吧,你可以分析字节码并重写汇编,看看这篇文章的结尾)。
对我来说,你的虚假假设似乎是错误的。你不需要和一个巨大的图书馆一起工作,这个图书馆可以保存你所有的帮助班级,真的,你不想要,或者你也不想要。如果你不喜欢这样的话,我向你保证,在时间上,也许多年,你会讨厌这种一对一的方法。
这正是您想要逃避的原因,这就是为什么.Net和许多其他语言/环境支持"库"的概念。或"模块"并且允许你使用它们中的多个,这就是为什么你到处看到的大多数项目都没有创建为"一个巨大的EXE"。当你把它放在较小的块中时,重用,分析甚至捕获bug会容易得多。
-
然而,如果你坚持,有些方法(丑陋)可以像你想的那样实现某些目标。我假设"巨大的DLL"在C#中,由你控制。
首先,有点简洁但有效的方法是使用"文件链接"。在VisualStudio中,您可以拥有一个包含大量文件和产品BigDLL" all.dll"的项目,只需在其旁边您可以创建另一个不包含任何文件的项目完全,但这将包含链接到第一个项目'文件即可。使用典型的"添加文件.."项目的选项,并注意到最后的"添加"按钮那里有一个向下箭头,扩展为"添加为链接.."。
这将导致文件保留在HugeProject中,但SmallProject也会看到该文件,当编译SmallProject时,它也将从该文件中提取代码。
请注意,通过这种方式,您将实际构建两个单独的模块程序集:大一个和小一个,并且您的最终产品将需要引用小的。
这种方式既简洁又丑陋,就像你手动将大型项目复制/拆分成较小的项目一样,但微不足道的优点是你不需要复制代码文件。
-
间接思考的中场休息:#if
有条件地关闭一些当前未使用的代码,但是设置驱动这些IF的标志会很麻烦-
第二种方法是将所有内容保存在HugeProject中,并让您的应用程序直接引用它,然后在构建和测试所有内容之后,在打包并发送给客户之前 - 使用某种修剪实用程序将检查引用的代码部分,并将从程序集中删除所有死代码。我无法为您提供此类实用程序的任何名称,但许多混淆器具有此类功能。
他们将运行您的编译的代码,交叉引用所有内容,更改/删除/删除类/方法/属性名称,并且他们可以作为奖励删除未使用的位。然后,他们会将损坏的程序集写回磁盘,确保它们在重整之前相互引用而不是原始程序集。
示例:See a question related to that
例如:See an example of such utility也考虑ILMerge以获得更好的结果。
缺点 - 实用程序可能会留下一些垃圾无法决定是否使用它,查找/测试/购买它可能需要一些时间和资源,因为剥离装配将会有一些签名问题如果只通过反射调用某些代码,这些实用程序会出现问题,并且可能需要您提供一些额外的提示或确保代码"似乎已被使用" (示例:"插件"整个命名空间实现" IPlugin"然后您的应用搜索NS的类型并使用Activator.CreateInstance实例化它们;没有硬连接的用法,微调可能决定删除所有插件,因为"未使用&#34 ;;您需要仔细配置修剪器或感到惊讶。
也许还可以找到其他一些方法,但严肃地说,在大多数情况下,你不想浪费你的时间,特别是手动。所以只需整理你的代码并将其拆分成小型库,或者开始寻找自动混淆器和修剪器。