为什么引用的DLL与EXE一起存储

时间:2014-11-06 22:30:58

标签: c# .net dll

我在解决为什么将DLL复制到带有引用它的exe的文件夹时遇到了一些麻烦。据我所知,我应该制作DLL的原因是拥有可重用的代码。因此,如果我创建一个由25个应用程序引用的DLL(从而使用"可重用代码"),那么当我需要在DLL中添加更改功能时(比如,更新幕后发生的事情) ,我必须打开并重新编译所有25个应用程序,以确保它们获得新功能。

我的一个具体示例是一个负责创建打印工单表单的DLL。工作订单表单的布局和外观已更改,但所包含的信息均未更改。在这种情况下,我只需要对底层表单创建代码进行一些更改,但不要更改该代码的实现(使用完全相同的方法和属性)。我不认为我需要重建DLL,然后重新引用每个引用它的应用程序,但似乎是这种情况。如果我不重建,那么应用程序将继续使用旧版本的DLL。

有解决方法吗?我不正确地思考它?我应该做别的吗?我是否完全误解了所有这些?感谢您提供的任何帮助。

4 个答案:

答案 0 :(得分:4)

  

有解决方法吗?

是 - install the library in the Global Assembly Cache (GAC)。这种方式可以被许多应用程序使用。

阅读How the Runtime Locates Assemblies以更好地了解如何加载引用。允许使用EXE部署DLL的实际原因是允许“XCOPY部署”。此外,它允许从NuGet和其他来源“插入”库,可以添加而无需“安装”它们。应用程序的Bolt-on扩展也更加简单,因为它们可以被复制,并且应用程序可以动态加载加载项而无需注册任何内容。

很多源于COM世界的痛苦,每个 DLL必须注册,如果你有多个不兼容的版本,你会发现自己在“DLL地狱” ”。 .NET通过允许使用可执行文件部署版本来放宽这些规则,但仍提供一种机制(GAC)以允许共享公共程序集。

您还可以阅读Simplifying Deployment and Solving DLL Hell with the .NET Framework以获取有关.NET如何使用程序集解决版本问题的更多背景信息

在您的情况下,可能可以将DLL复制到所有新应用程序,但有一些因素可能会阻止它:

  • 如果程序集已签名
  • 如果应用程序需要特定版本的程序集

答案 1 :(得分:1)

DLL有多种用途。理论目的之一是允许多个进程共享同一个DLL。事实上,如果你在GAC中安装一个DLL,那么.NET可以允许.NET实际将DLL加载到内存中(即同时运行多个进程,使用相同的DLL,不要让每个进程结束他们自己的内存副本,就像其他DLL一样。)

但另一个目的仅仅是代码重用。在这种情况下,DLL的主要功能是作为某些给定功能的可再发行的存储库。多个进程可以使用DLL的相同副本并不重要。相反,重要的是多个进程可以方便地重用DLL中的功能。

另请注意,对DLL的更改可能有用也可能没有用。当然,人们总是希望更新版本的DLL更好。但是对代码的更改总是意味着有机会在代码中添加新的错误。使用给定版本的DLL进行全面测试的程序在与较新版本的同一DLL一起使用时可能保持可靠,也可能不保持可靠。

较新版本的DLL通常主要用于添加功能。当然,在这个过程中可能会修复一些错误,但如果程序已经使用旧版本进行了测试并且当前正在运行,那么新的错误修复可能并不重要。与此同时,用旧版本编写的程序可能没有任何实用的方法来利用更新的功能。

磁盘空间便宜,内存几乎便宜。并为每个程序提供自己的副本,以防止新版DLL中的意外更改干扰仅使用旧版本测试的程序。

最后请注意,即使使用GAC,也可以安装多个版本的DLL。因此,如果DLL满足必要的要求,则可以显着减少DLL版本的问题。

答案 2 :(得分:0)

听起来你有构建自动化问题(或缺乏)。如果您将所有代码放在一个容器(TFS,GIT等)中,则没有理由不能将所有项目添加到单个主构建解决方案中并以这种方式分发代码。这样 - 您只需进入并重新编译主解决方案,文件就会被推送到所有应用程序。

另一种选择是使用公共bin文件夹并将所有项目输出到该主目录并从那里执行它们。这只需要你重新编译DLL,其他应用程序会立即选择它。

第三个选项是在DLL项目上建立一个后期构建步骤,将该文件复制到所有相关目录中。我不推荐这种方法,因为维持这将是一场噩梦。

所有这些都没有考虑您使用/部署应用程序的方式以及您必须考虑的用户/环境数量。

答案 3 :(得分:0)

使用DLL的一个较少讨论的优点是它们可以帮助您构建代码。

将产品拆分为DLL可以让每个组件的开发人员更好地控制可访问性,因为您现在可以使用公共,私有和内部范围。因此,例如,您可以在单个DLL中拥有一组紧密耦合的类,而不会让其他DLL中的代码滥用允许紧密耦合的接口。

将产品拆分为DLL还会强制您在组件之间建立依赖关系时考虑构建顺序。

你当然可以尝试在高级设计中保持层次的勤奋和纪律,但是当你添加了一个不应该依赖的依赖时,没有什么可以让你知道。在那里。当然也存在各种方法,但是将项目拆分为DLL并依次构建它会迫使您非常明确地添加不遵循简单分层模型的依赖项。

如果您计划使用第三方插件使您的产品可扩展,那么拥有一个定义应用程序及其插件之间接口的DLL通常会很有帮助。这使得插件开发人员更容易知道支持的API中的内容是什么。即使您只是使用可扩展性模型来组织由同一公司内的大型团队(或一组团队)开发的代码,相同的技术也会有所帮助。