46

什么时候应该安装到 GAC 中,什么时候不应该?(实际上,我指的是在客户购买我们的产品后安装在他们的机器上)。

  1. 我有一个仅用于我的一个应用程序(GAC 或无 GAC)的程序集?

  2. 我有一个所有应用程序共享的程序集(GAC 或非 GAC)?

  3. 我的所有应用程序都可能使用不同版本的程序集(GAC 或非 GAC)?

这是三种情况……但我相信还有更多。我不一定只寻找这三个问题的答案。

类似的问题:使用 GAC 的优点和缺点是什么?

4

7 回答 7

39

一般 MS 指南

GAC 实际上是 Microsoft 通用 .NET 库的存储库。是的,他们也让开发人员使用它,但根据经验,如果您不需要 GAC,请不要使用它。如果没有伤害,请保持简单和本地化。

  • 我只会出于性能原因考虑 GAC,例如,如果您有一些大型程序集,请尝试将它们放入 GAC 和NGEN中。它应该会显着提高性能。Microsoft 在安装期间为所有标准 .NET 框架程序集执行此操作(现在您知道为什么安装需要这么长时间了)。Paint.NET 也这样做(以改善他们的应用程序的启动时间)。然而,我们大多数人并不在大型框架或 Photoshop 竞争对手上工作,所以大多数时候,在 GAC 中进行组装所带来的性能提升是微乎其微的。不值得放弃简单的 x-copy 部署。

  • 一些开发人员可能会使用 GAC 来确保权限不足的用户无法删除或修改他们的程序集。

  • 对于其他人来说,这可能是出于版本控制的原因,但在这里你真的应该重新考虑。我不会重复已经说过的话,你可以在这里阅读为什么

并且不要忘记,一旦您想部署到 GAC 中,您的安装程序将需要管理员权限,您几乎可以忘记单击一次部署等...

于 2009-01-31T05:59:11.107 回答
16

GAC 的有用案例:

  • COM 可调用代码 - 即您希望一些非 .NET 代码能够访问您而不会弄乱 dll 等
  • 服务组件(COM+)
  • 如果您正在编写如此常见的代码,那么使用 GAC (主要是 .NET 框架组件等)实际上是有意义的
  • 如果您想使用NGEN对代码进行预 JIT

除此之外,我倾向于像避免瘟疫一样避免 GAC。通过robocopyetc 为您的应用程序部署必要的 dll 要容易得多;这提供了隔离易于部署。

于 2009-01-31T09:29:15.847 回答
8

如果您正在安装asp.net Web 应用程序并且您是所有者并且可以完全控制机器,那么在某些情况下,将您计划在全局程序集缓存中跨站点/Web 实例共享的程序集放置可能是有意义的。

如果将程序集放在 GAC 中,则可以显着改善具有相同 ASP.NET 应用程序的多个多个实例的服务器上的应用程序的初始加载时间和内存使用情况。至少我在我们的服务器上看到了这个,有几十个安装。

于 2009-01-31T07:31:52.353 回答
6

如果您要交付一个由多个程序集组成的可重用库,但其中只有几个程序集构成一个外观,那么您可以考虑将程序集安装到 GAC 中,前提是该程序包已安装到开发人员的 PC 上。

想象一下,您运送了 6 个组件,而这 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 。但是当他们的项目运行时,它必须能够以递归方式加载它引用的所有程序集。如何做到这一点?通常,它们必须在 GAC 中的 Bin 文件夹中可用:

  • 您可以要求开发人员找到您的安装文件夹并添加对您放置在那里的所有 N 个程序集的引用。这将确保它们将被复制到 Bin 文件夹中,以便在运行时可用。
  • 您可以安装已经包含这 6 个引用的VS.NET 项目模板。有点复杂,因为您应该在安装之前将程序集的实际路径注入此模板。这只能由安装程序完成,因为此路径取决于安装路径。
  • 您可以要求开发人员在 .csproj / .vbproj 文件中创建一个特殊的构建后步骤,将必要的依赖项复制到 Bin 文件夹。相同的缺点。
  • 最后,您可以将所有程序集安装到 GAC中。在这种情况下,开发人员必须从他们的项目中添加对 MyProduct.Facade.dll 的引用。无论如何,其他一切都将在运行时可用。

注意:最后一个选项不会让您在将项目运送到生产 PC 时做同样的事情。您可以在 Bin 文件夹中发送所有程序集,也可以将它们安装到 GAC 中 - 一切都取决于您的意愿。

因此,所描述的解决方案显示了在开发过程中将第三方程序集放入 GAC 的优势。与生产无关。

您可能会发现,安装到 GAC 中主要是为了解决所需程序集(依赖项)的位置问题。如果程序集安装到 GAC 中,您可能会认为它存在于“附近”任何应用程序。这就像将 .exe 的路径添加到您的 PATH 变量中,但是以“托管方式”。 - 当然,这是相当简化的描述;)

于 2009-06-21T16:00:26.973 回答
3

这是来自 Chris Sells 的链接,名为“Avoid the GAC”

https://sellsbrothers.com/12503

解释很长,但简而言之,他确定的两个案例是

  1. 在不接触受影响的应用程序的情况下修复严重错误(并且不破坏任何东西!)

  2. 在运行时在单独部署的程序集之间共享类型

注意:克里斯的帖子末尾有一个很长的讨论线程,非常好的评论列表。

于 2009-01-31T07:41:16.733 回答
0

首先,如果您在客户端计算机上安装此应用程序,则需要添加一个自定义操作以在 GAC 中安装该应用程序,并在删除时添加另一个操作。

案例 A 绝对不是 GAC

在案例 B 上,如果您的库会不断变化,您将需要每次都将程序集的每个版本添加到 gac 并更新到该程序集

在案例 C 中并排执行允许您运行不同的程序集版本,并且您不需要添加任何内容来区分版本。

仅在您确实需要时使用

于 2009-01-31T06:05:15.867 回答
0

如果同一台服务器上的大量 Web 应用程序将共享完全相同的库,那么安装到 GAC 中才有意义。例如,在 Sharepoint 服务器上可能有数百个网站都需要共享同一个 Web 部件,因此在这种情况下,将编译后的 Web 部件部署到 GAC 是有意义的。

于 2009-01-31T09:24:58.413 回答