使用GAC的优缺点是什么?

55

此外,是否存在必须使用全局程序集缓存或不能使用全局程序集缓存的情况?


当我自己研究这个主题时,我发现揭秘.NET全局程序集缓存由_Jeremiah Talkar_帮助了我很多。 - Espo
9
已经有足够的答案了,但我再强调一遍:永远不要部署到GAC,否则会导致部署成为噩梦。 - Tigraine
不错的参考资料 http://www.codeproject.com/KB/dotnet/demystifygac.aspx - T.S.
7个回答

49
  • 从GAC加载程序集意味着减少开销和确保应用程序始终加载正确版本的.NET库而提高安全性。
  • 不要ngenn在GAC之外的程序集,因为在许多情况下甚至会降低性能,几乎没有性能收益。
  • 您已经在使用GAC,因为所有标准的.NET程序集实际上都在GAC中并且是在安装期间ngened。
  • 将自己的库放入GAC会增加部署复杂性,我建议尽量避免。
  • 如果您想将某些内容放入GAC,则用户在安装过程中需要以管理员身份登录,这对许多类型的应用程序来说是个问题。

总之,简单起见开始,如果您稍后发现将程序集放入GAC并ngened可以获得重大性能提升,请尝试,否则不要费心。 GAC更适合框架,其中预计库将在多个应用程序之间共享,在99%的情况下,您不需要它。


2
@Sam:请查看http://msdn.microsoft.com/en-us/magazine/cc163610.aspx,特别是"Assemblies and the GAC"部分。 - lubos hasko

23

好处:

  • 只需要更新一个程序集的地方
  • 节省一点硬盘空间

坏处:

  • 如果你只需要更新其中一个网站,你不能仅更新它,否则其他网站可能会出现问题。

建议:把GAC留给微软和友好的开发者。现在存储一千兆非常便宜。


18

GAC也可被用于需要提升权限以代表不太信任的代码执行特权操作的程序集(例如,部分信任的ASP.NET应用程序)。

例如,假设您有一个部分信任的ASP.NET应用程序,需要执行需要提升权限(即完全信任)的任务。解决方案是将需要提升权限的代码放入单独的程序集中,该程序集标记有AllowPartiallyTrustedCallers属性,包含特权逻辑的类标记有PermissionSet属性,类似于:

[PermissionSet(SecurityAction.Assert, Unrestricted=true)]

我们的程序集会被赋予一个强名称(签名),然后部署到全局程序集缓存中。

现在,我们的部分信任应用程序可以利用全局程序集缓存中的受信任程序集来执行一组特定而狭窄的特权操作,而不会失去部分信任的好处。


7
如果您正在发布由多个程序集组成的可重用库,但只有其中几个形成了外观,则可以考虑在安装包安装到开发人员的计算机上时将程序集安装到GAC中。
假设您发布了6个程序集,其中只有一个程序集包含外观 - 即其他5个程序集仅由外观本身使用。您发布:
- MyProduct.Facade.dll - 这是唯一供开发人员使用的组件 - MyProduct.Core.dll - 由MyProduct.Facade.dll使用,但不适合供开发人员使用 - MyProduct.Component1.dll - 同上 - MyProduct.Component2.dll - 同上 - ThirdParty.Lib1.dll - 由MyProduct.Component1.dll使用的第三方库 - ThirdParty.Lib2.dll - 同上 - 等等。
使用您的项目的开发人员希望在自己的项目中仅引用MyProduct.Facade.dll。但是,当他们的项目运行时,它必须能够递归地加载所有引用的程序集。如何实现这一点?一般来说,它们必须在Bin文件夹中或GAC中可用:
- 您可以要求开发人员定位您的安装文件夹并添加对您放置在那里的所有N个程序集的引用。这将确保它们会被复制到Bin文件夹中以便在运行时可用。 - 您可以安装VS.NET项目模板,其中已经包含这6个引用。有点复杂,因为您应该在其安装之前将实际路径注入此模板中。由于此路径取决于安装路径,因此只能由安装程序完成。 - 您可以要求开发人员在.csproj / .vbproj文件中创建一个特殊的后期构建步骤,将必要的依赖项复制到Bin文件夹中。同样的缺点。 - 最后,您可以将所有程序集都安装到GAC中。在这种情况下,开发人员必须仅向其项目添加对MyProduct.Facade.dll的引用。其他所有内容都将在运行时可用。
注意:最后一种选项不会强制您在将项目发布到生产计算机时执行相同操作。您可以将所有程序集都放在Bin文件夹中或将它们安装到GAC中 - 一切都取决于您的意愿。
因此,所描述的解决方案显示了在开发过程中将第三方程序集放入GAC中的优势。这与生产无关。
正如您可能发现的那样,将程序集安装到GAC中主要旨在解决所需程序集(依赖项)的位置问题。如果程序集安装到GAC中,则可以认为它存在于任何应用程序“附近”。这就像将.exe的路径添加到您的PATH变量中,但以“托管方式”进行。当然,这是相当简化的描述。

这很不错。非常不错。我们正在使用一个 COBOL .NET 第三方编译器,它编译一个 .dll 然后调用第三方的 .dll,我们试图从 VB6 中调用它,只添加我们创建的引用而不是第三方的引用。如果我没有读到这个,我永远不会想到这个。 - interesting-name-here

7
GAC(全局程序集缓存)具有完全信任并可被Web应用程序之外的应用程序使用。例如,在Sharepoint中,计时器作业必须在GAC中,因为sptimer服务是一个单独的进程。
“完全信任”部分也可能是安全问题的可能来源。当然,您可以使用代码访问安全性,但不幸的是,我没有看到太多程序集使用CAS。/bin文件夹可以锁定为中等级别,通常是可以接受的。
Daniel Larson也在其博客中详细介绍了CAS的区别。

6

我认为使用全局程序集缓存(GAC)的最大优势之一是可以注册并使多个相同版本的程序集可供应用程序使用。但就个人而言,我不喜欢它限制了从一台机器到另一台机器的移动(我不喜欢在新的虚拟计算机上检查源代码并执行一系列步骤以使其运行,因为我必须在GAC中注册一些内容)。


3

在我的生涯中,我只遇到过一个需要将程序集放入全局程序集缓存(GAC)的应用程序。这是因为这些程序集是许多应用程序都会使用的框架的一部分,将它们放入GAC似乎是正确的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接