何时以及何时不安装到 GAC 中?

Posted

技术标签:

【中文标题】何时以及何时不安装到 GAC 中?【英文标题】:When and when-not to install into the GAC? 【发布时间】:2010-10-04 15:27:29 【问题描述】:

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

    我的程序集只能用于我的一个应用程序(GAC 或非 GAC)?

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

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

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

类似问题:What are the advantages and disadvantages of using the GAC?

【问题讨论】:

【参考方案1】:

一般 MS 指南

    没有 没有 没有

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

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

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

对于其他人来说,这可能是出于版本控制的原因,但在这里您真的应该重新考虑。我不会重复已经说过的话,you can read here why。

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

【讨论】:

如果我正在构建自己的服务器软件......那么将其放入 GAC 会有助于提高性能吗? 本地程序集(未放置在 GAC 中)有额外的开销,但仅在启动期间。然后是 NGEN 与 JIT。 NGENed 程序集(但仅限于 GAC 中的程序集)应该会缩短启动时间,但 JITed 程序集应该具有更好的运行时性能 - 理论上。您需要在自己的应用上对此进行衡量。【参考方案2】:

GAC 的有用案例:

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

除此之外,我倾向于像避免瘟疫一样避免 GAC。通过robocopy 等在您的应用程序中部署必要的dll 要容易得多;这使得隔离易于部署。

【讨论】:

【参考方案3】:

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

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

【讨论】:

为什么“内存使用”会受到影响?我们看到了类似的事情,哎呀......我不在乎这个问题已经 9 岁了!【参考方案4】:

如果您要交付一个由多个程序集组成的可重用库,但其中只有几个程序集构成外观,那么您可以考虑将这些程序集安装到 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。但是当他们的项目运行时,它必须能够以递归方式加载它引用的所有程序集。如何做到这一点?通常,它们必须在 Bin 文件夹中,在 GAC 中可用:

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

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

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

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

【讨论】:

【参考方案5】:

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

https://sellsbrothers.com/12503

解释很长,但简而言之,他确定的两种情况是

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

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

注意:有一个很长的讨论帖 at the end of Chris's the post,非常好的 cmets 列表。

【讨论】:

【参考方案6】:

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

案例 A 绝对不是 GAC

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

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

仅在您确实需要时使用

【讨论】:

【参考方案7】:

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

【讨论】:

以上是关于何时以及何时不安装到 GAC 中?的主要内容,如果未能解决你的问题,请参考以下文章

何时向托管对象添加类别以及何时使用瞬态属性?

PWA 何时以及如何更新自身?

何时使用类别以及何时使用子类化? [关闭]

电子邮件标题中的特殊字符是啥以及何时使用引号?

何时使用SESSION以及何时在Web应用程序中使用GET进行参数传递?

如何以及何时放弃在 C# 中使用数组?