谁应该将共享 .NET 库安装到 GAC? 提供库的框架? 每个使用它的应用程序? 两个都?

发布于 2024-07-19 13:33:22 字数 505 浏览 7 评论 0原文

也许这更像是一个哲学问题。

假设我有某种框架,并且我决定提供一个 .NET 库,使该框架的某些方面的使用更加容易。 我不希望每个使用该框架的应用程序在本地携带该库的副本,因此我希望它位于 GAC 中(即使存在这可能意味着的所有维护问题。)

我可以让框架将库安装到GAC 非常容易,因此每个应用程序都不必这样做。 但是,当我创建新版本的库时,我的框架安装程序必须同时携带旧库和新库,以确保升级不会删除某些应用程序可能正在使用的旧库。

但是,如果每个应用程序也将库安装到 GAC,Windows Installer 引用计数就会启动,并且我的框架不再需要担心在升级场景中携带旧库。 仅当最后一个 Windows Installer 引用消失时,才会卸载正在使用的库。

显然,每个应用程序在构建应用程序时都可以访问该库,并且可以轻松地将其包含在其安装程序中。

有人对其中一方与另一方有意见/观点/经验吗? 我意识到这并不是严格要求的问题类型(因为它会引发讨论),但我认为简短的讨论会很有用。

This is more of a philosophical question, perhaps.

Let's say I have a framework of some sort and I decide to provide a .NET library that makes the use of certain aspects of the framework easier. I don't want each application that uses the framework to carry a copy of the library locally, so I want it in the GAC (even with all the maintenance issues that that might imply.)

I can have the framework install the library into the GAC pretty easily so each app doesn't have to. But then when I create a new version of the library, my framework installer has to carry both the old and the new library to make sure upgrades don't remove the old library that might be in use by some application.

However, if each application also installs the library to the GAC, Windows Installer reference counting kicks in, and my framework no longer has to worry about carrying old libraries around in the upgrade scenario. An in-use library will only get uninstalled when the last Windows Installer reference is gone.

Obviously, each application has access to the library at the time the application is built and can easily include it in its installer.

Does anybody have an opinion/viewpoint/experience of one vs. the other? I realize this is not strictly the desired type of question (since it invites discussion), but I think a short discussion would be useful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

罪歌 2024-07-26 13:33:23

您的框架的每个新版本都向后兼容吗? 您是否曾弃用组件或更改接口?

假设上述问题是否定的,您可以增加版本,让新库卸载旧版本并安装新版本。 然后使用 GAC 策略文件将旧版本映射到新版本。 这样,引用旧库的应用程序就不必更改,并且将映射到新版本。

这是一个有关创建策略文件的问题

< a href="http://msdn.microsoft.com/en-us/library/dz32563a.aspx" rel="nofollow noreferrer">有关发布者策略文件的 MS 文档

以下内容将强制所有应用程序引用 1.0。 0.0 以使用较新的 2.0.0.0。 我相信您也可以使用通配符。

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="myAssembly"
                       publicKeyToken="32ab4ba45e0a69a1"
                       culture="en-us" />
                <!-- Redirecting to version 2.0.0.0 of the assembly. -->
                <bindingRedirect oldVersion="1.0.0.0"
                      newVersion="2.0.0.0"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

Is each new version of your framework backward compatible? Do you ever deprecate components or change interfaces?

Assuming NO to the questions above, you could increment the versions, have the new library uninstall the old version and install the new one. Then use a GAC Policy file to map the old version to the new version. That way, applications referencing the old library, would not have to change, and would be mapped to the new version.

Here is a SO questions about creating Policy Files

MS documentation on publisher policy files

The following would force any application referencing 1.0.0.0 to use the newer 2.0.0.0. I believe you can also use wildcards.

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="myAssembly"
                       publicKeyToken="32ab4ba45e0a69a1"
                       culture="en-us" />
                <!-- Redirecting to version 2.0.0.0 of the assembly. -->
                <bindingRedirect oldVersion="1.0.0.0"
                      newVersion="2.0.0.0"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>
蓦然回首 2024-07-26 13:33:23

我们也确实需要多种产品,对于我们的框架,我们只使用 MSI 合并module,在每个产品中都会引用。

<Feature ...>
  ...
  <MergeRef Id="FrameworkMergeModule" />
</Feature>
...
<Directory ...>
  <Merge Id="FrameworkMergeModule" SourceFile="..\Tools\Framework.msm" ... />
</Directory>

没有发现这种方法有任何问题,正如您所说,引用计数发挥了作用。

要让程序集进入 GAC(强命名,wix 中需要多做一些工作)需要跳过额外的环节,但没什么大不了的。 如果您使用 GAC 或只是将简单的 xcopy 部署到安装目录(通过 wix-fu),则此方法有效。

我们(在强命名程序集之后)使用的主要痛苦是在深入研究之前没有完全理解 AssemblyVersion 和 AssemblyFileVersion 属性。 .您实际上只想在真正需要时更改 AssemblyVersion,并研究构建和/或修订版本的通配符引用以使事情变得更容易(假设您有严格的版本控制策略)

We also have this exact need for multiple products, and for our framework we just use an MSI merge module, which is referenced in each product.

<Feature ...>
  ...
  <MergeRef Id="FrameworkMergeModule" />
</Feature>
...
<Directory ...>
  <Merge Id="FrameworkMergeModule" SourceFile="..\Tools\Framework.msm" ... />
</Directory>

Have found no problems with this approach, as you said, reference counting does its job.

There are extra hoops to jump through to get assemblies into the GAC (strong naming, a little more work in wix) but nothing major. This approach works if you use the GAC or just do plain xcopy deployment into the install directory (via wix-fu)

The main pain we felt (after strong naming an assembly) using was not understanding AssemblyVersion and AssemblyFileVersion attributes fully before diving in...you really only want to change AssemblyVersion when there is a genuine need, and look into wildcard referencing for Build and/Or Revision versions to make things a little easier (assuming you have a disciplined versioning strategy)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文