首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >部分引用DLL

部分引用DLL
EN

Stack Overflow用户
提问于 2015-06-26 19:15:44
回答 2查看 117关注 0票数 0

我有一个库动态链接库与排序算法,解析器,验证器,转换器等充满。动态链接库大约是40Mb(这不是我所知道的很多,但仍然)。现在,我只想引用该DLL的解析器。重点是在不向客户交付40Mb的情况下获得这些解析器。

有没有办法在每次发布构建时,从我的库中获取这些最新的解析器,将它们存储到某种.partialDll文件中,然后只将它们交付给客户?结果就是我把我所有的助手类都放在一个不断增长的大库中,然后客户就可以得到他们订购的东西了。

我想我需要进行大量的思考才能达到这样的效果,对吧?有什么想法吗?

EN

回答 2

Stack Overflow用户

发布于 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项目)。

票数 3
EN

Stack Overflow用户

发布于 2015-06-26 20:21:49

一般来说,不,没有办法做到这一点。一旦你将“一切”打包到一个模块中并编译它,你就不能在以后将该模块拆分成更小的模块。(好吧,好吧,你可以分析字节码并重写程序集,请参阅本文的结尾)。

对我来说,你的零假设似乎是错误的。你不需要使用“一个巨大的库来保存你所有的助手类”,真的,你不想要,或者你也不想要。如果你没有这样的感觉,我向你保证,随着时间的推移,也许几年后,你会讨厌这种一刀切的方法。

这正是你想要摆脱的,这就是为什么.Net和许多其他语言/环境支持“库”或“模块”的概念,并允许你使用它们中的多个,这也是为什么你在任何地方看到的大多数项目都不是作为“一个巨大的可执行文件”创建的。当你把它放在较小的块中时,重用、分析甚至寻找bug都会变得更容易。

--

然而,如果你坚持,有一些方法(丑陋的)可以达到你想的那样。我假设“巨型动态链接库”是用C#编写的,并由您控制。

首先,有些天真但有效的方法是使用“文件链接”。在VisualStudio中,你可以有一个包含大量文件的项目,并且生成一个BigDLL "all.dll",在它的旁边,你可以创建另一个项目,它将任何文件,但它将包含到第一个项目的文件的链接。使用典型的“添加文件..”选项添加到项目中,请注意,在最后一个“添加”按钮附近有一个向下箭头,它展开为“添加为链接..”。

这将导致文件停留在HugeProject中,但SmallProject也会看到该文件,并且在编译SmallProject时,它也会从该文件中提取代码。

请注意,通过这种方式,您实际上将构建两个独立的模块程序集:一个大模块,一个小模块,并且您的最终产品将需要引用小模块。

这种方式既幼稚又丑陋,就像你手动复制/拆分了一个巨大的项目,但它的一个小优点是,你不需要复制代码文件。

--

中场休息:

  • 您可以使用#if有条件地关闭一些当前未使用的代码,但是将驱动这些IF的标志设置为cumbersome
  • you可以编辑.csproj文件并使用MSBuild条件子句在最终生成期间自动从HugeProject中排除未使用的代码文件,但是设置驱动这些IF的标志也会很麻烦

--

第二种方法是将所有内容都保存在HugeProject中,并让您的应用程序直接引用它,然后在构建和测试所有内容之后,在打包并发送给客户之前-使用某种修剪实用程序来检查代码的哪些部分被引用,并从程序集中删除所有死代码。我不能给你任何这样的工具的名字,但许多模糊都有这样的功能。

它们将遍历您编译的代码,交叉引用所有内容,更改/删除/trash类/方法/属性名称,还可以删除未使用的部分。然后,它们会将损坏的程序集写回磁盘,确保它们相互引用,而不是损坏前的原始程序集。

示例:See a question related to that

示例:See an example of such utility也考虑使用ILMerge以获得更好的结果。

缺点-实用工具可能会留下一些垃圾它无法决定是否使用它,查找/测试/购买它可能需要一些时间和资源,你可能会有一些签名问题,因为剥离的程序集将是一个全新的程序集,等等。同样,如果你只是通过反射调用一些代码,它可能需要你提供一些额外的提示或确保代码“似乎被使用了”(例如:实现"IPlugin“的整个”插件“命名空间,然后你的应用程序在NS中搜索类型并使用Activator.CreateInstance来实例化它们;没有硬链接的用法,trimmer可能会决定将所有插件删除为“未使用”;你需要仔细配置trimmer,否则会感到惊讶)。

也许还可以找到其他一些方法,但说真的,在大多数情况下,你都不想浪费时间,尤其是手动。因此,只需整理代码并将其拆分成小的库,或者开始寻找自动混淆器和修剪器。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31071806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档