引用全局程序集缓存
我有一个项目需要使用 NHibernate 与我的 Oracle 数据库进行通信。
我工作场所的许多项目都使用NHibernate,因此NHibernate程序集被放置在全局程序集缓存中,这是一个我不太理解的工具。根据我的研究,我收集了以下内容:
- 全局程序集缓存是 dll 的中央存储库被很多项目引用。这避免了 DLL Hell 的问题 - 当您的 dll 的新版本发布时,您在缓存中更新它一次,并且引用它的所有 .NET 项目现在都将使用新版本。
- 您无法添加对程序集缓存中程序集的引用。 "具有已在 GAC 中注册的将不会出现在[添加参考]列表中”。但是,您可以通过破坏注册表来强制显示它们。
- 您可以轻松添加对程序集缓存中程序集的引用。 “只需使用“添加引用”窗口可添加对已安装在 GAC 中的程序集的引用”。 (我倾向于不相信这一点,因为我在“添加引用”窗口中没有看到任何 GAC 程序集)。
- 我工作场所的几个项目确实参考了 GAC 中的许多集会。这些程序集从未出现在“添加引用”菜单中,因此我知道我的前任没有使用注册表修改技术。但它们显然源自 GAC - 它们的文件路径是 C:\Windows\Assembly 的子目录。
第二点显然与其他三点相矛盾,但如果它只是错误的,我在引用库时就不会有任何问题。它绝对反映了现实,因为我的 GAC 程序集在“添加引用”窗口中找不到。
我想知道两件事:
- 开发人员什么时候会想要使用 GAC?有什么好处 没有注册表欺骗就无法引用的库?
- 我的前辈们在参考文献库方面采取了哪些步骤? GAC,不触及注册表?
I have a project which needs to use NHibernate to communicate with my Oracle database.
Many projects at my workplace use NHibernate, so the NHibernate assembly was placed in the Global Assembly Cache, a tool that I do not entirely understand. From my research, I have gathered the following:
- The Global Assembly Cache is a central repository for dlls which are referenced by many projects. This dodges the problem of DLL Hell - when a new version of your dll is released, you update it in the cache a single time, and all .NET projects that reference it will now use the new version.
- You cannot add a reference to an assembly in the assembly cache. "Assemblies that have been registered in the GAC will not appear in [the Add Reference] list". You can, however, forcibly make them appear by mutilating the registry.
- You can easily add a reference to an assembly in the assembly cache. "simply use the Add Reference window to add a reference to an assembly you've installed in the GAC". (I'm inclined not to believe this, since I don't see any GAC assemblies in my Add Reference window).
- Several projects at my workplace do have references to many assemblies in the GAC. Those assemblies never appear in the "Add Reference" menu, so I know my predecessors did not use the registry mangling technique. Yet they clearly originate from the GAC - their file path is a subdirectory of C:\Windows\assembly.
Point two obviously contradicts the other three, but if it were simply false, I wouldn't have any problems referencing libraries. It definitely reflects reality in that my GAC assemblies are nowhere to be found in the "Add References" window.
I would like to know two things:
- When would a developer ever want to use the GAC? What good is a
library that can't be referenced without registry trickery? - What steps did my predecessors take to reference libraries in the
GAC, without touching the registry?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不,这就是所谓的 DLL 地狱。应用程序引用程序集的特定版本。您可以更新 DLL 并更新使用它的应用程序。并且不要破坏也使用该 DLL 但未重新编译的旧应用程序。您可以使用 GAC 来做到这一点,因为它可以存储 DLL 的多个版本。或者,您可以通过将 DLL 保留在与应用程序的 EXE 相同的目录中来轻松完成此操作。
GAC 中的程序集不会出现在“添加引用”对话框中。因此,您必然不知道用户在其 GAC 中存储了哪些内容。您可以使用开发计算机上的“浏览”选项卡,这样您就可以确保使用特定的 DLL 版本。
GAC 对于需要分发安全更新的公司非常重要。就像微软一样。它确保不存在未修补的 DLL 副本。对于 [ComVisible] 程序集解决 COM 的 DLL Hell 问题也很重要。就是这样。
No, that's called DLL Hell. Applications reference a specific version of an assembly. You can update a DLL and update an application that uses it. And not break an old application that uses that DLL as well but didn't get recompiled. You can do that with the GAC because it can store multiple versions of a DLL. Or you can do this just as easily by keeping the DLL in the same directory as the application's EXE.
Assemblies in the GAC do not appear in the Add Reference dialog. Necessarily so, you don't know what your user has stored in her GAC. You use the Browse tab on your dev machine instead so you'll be sure that you use a specific build of the DLL.
The GAC is important to companies that need to distribute security updates. Like Microsoft. It ensures that there are no unpatched copies of the DLL floating around. Also important for [ComVisible] assemblies to solve COM's DLL Hell problem. That's about it.
在项目中添加 GAC 引用的“强力”方法是直接编辑项目文件。卸载项目并在与项目中的其他引用相同的
ItemGroup
元素下添加一个Reference
,例如:您需要意识到设计之间存在差异-“添加引用”对话框的 .NET 选项卡中程序集的时间位置以及对 GAC 中程序集的这些引用的运行时解析。通过 .NET 选项卡和文件浏览选项卡添加引用之间的区别在于,前一种情况下的引用未标记为“复制本地”,因此在运行时将从 GAC 中查找。 Microsoft 通常会将要从 GAC 引用的程序集副本放置在 %programfiles%\Reference Assemblies 目录下的文件夹中,但这些仅在设计时使用。
A "brute force" method of adding a GAC reference in your project is to directly edit the project file. Unload the project and add a
Reference
under the sameItemGroup
element as the other references in your project, for instance:You need to be aware that there is a difference between the design-time location of assemblies in the .NET tab of the "Add Reference" dialog and the runtime resolution of those references to assemblies in the GAC. The difference between adding a reference via the .NET tab and the file browse tab is that the reference in the former case isn't marked as "Copy Local" and therefore at runtime will be looked up from the GAC. Microsoft typically places a copy of assemblies intended to be referenced from the GAC in folders under the %programfiles%\Reference Assemblies directory but these are only used at design-time.
不完全是。您可以控制应用程序是使用新版本还是旧版本。有趣的是两者可以同时在 GAC 中。
只需 a) 使用
GacUtil /i
注册它,然后 b) 添加引用,浏览到原始 dll 位置。 c) 验证新引用是否具有 CopyLocal=false 且 StrongName=trueNot exactly. You can control whether an app uses the new or the old version. The nifty thing is both can be in the GAC at the same time.
Simply a) register it with
GacUtil /i
and b) Add Reference, browse to the original dll location. c) verify that the new ref has CopyLocal=false and StrongName=true这似乎是我的前辈在 GAC 中添加对程序集的引用的方式:
然而,看看其他答案,我怀疑这不是一个好主意。碰巧的是,开发、测试和生产环境的 GAC 都是相同的。如果 GAC 未同步,则引用可能不会保持有效。
This appears to be how my predecessors added a reference to an assembly in the GAC:
However, looking at the other answers, I doubt that this is a good idea. It just so happens that the GACs for the development, testing, and production environments are all identical. If the GACs weren't synced, the references probably would not remain valid.
也许现在回答已经太晚了,但我找到了一种非常简单的方法来做到这一点(无需破解)。
希望它有帮助
May be it's too late to answer, but i found a very simple way to do this(without a hack).
Hope it helps