gpt4 book ai didi

c# - 如何解决 NuGet 依赖 hell

转载 作者:IT王子 更新时间:2023-10-29 03:52:43 32 4
gpt4 key购买 nike

我开发了一个名为 CompanyName.SDK 的函数库,它必须集成到公司项目 CompanyName.SomeSolution

CompanyName.SDK.dll 必须通过 NuGet 包部署。CompanyName.SDK 包依赖于第 3 方 NuGet 包。举个好例子,我们以 Unity 为例.当前依赖于 Unityv3.5.1405-prerelease

CompanyName.SomeSolution.Project1 依赖于 Unity v2.1.505.2CompanyName.SomeSolution.Project2 依赖于 Unity v3.0.1304.1

CompanyName.SDK 集成到此解决方案中会增加对 Unity v3.5.1405-prerelease 的依赖。假设 CompanyName.SomeSolution 有一个可运行的输出项目 CompanyName.SomeSolution.Application 依赖于上述两个和 CompanyName.SDK

问题就在这里开始了。所有 Unity 程序集在所有包中都具有相同的名称,没有版本说明符。在目标文件夹中,它将只有一个版本的 Unity 程序集:v3.5.1405-prerelease 通过 app.config 中的 bindingRedirect

Project1Project2SDK 中的代码如何使用它们被编码、编译和测试的依赖包的确切需要版本与?

注意 1: Unity 只是一个示例,如果 3rdparty 模块依赖于另一个同时具有 3-4 个版本的 3rdparty 模块,则实际情况要差 10 倍。

注意 2:我无法将所有包升级到最新版本,因为有些包依赖于其他包的非最新版本。

注意 3: 假设依赖包在版本之间有重大变化。这是我问这个问题的真正问题。

注意 4: 我知道问题 about conflicts between different versions of the same dependent assembly但那里的答案并不能解决问题的根源 - 他们只是隐藏它。

注意 5: promise 的“DLL hell ”问题解决方案到底在哪里?它只是从另一个位置重新出现。

注意 6:如果您认为使用 GAC 在某种程度上是一种选择,请编写分步指南或给我一些链接。

最佳答案

Unity 包不是一个很好的例子,因为你应该只在一个叫做 Composition Root 的地方使用它。 . Composition Root 应该尽可能靠近应用程序入口点。在您的示例中,它是 CompanyName.SomeSolution.Application

除此之外,我现在工作的地方出现了完全相同的问题。而我所看到的,问题通常是由诸如日志记录之类的横切关注点引入的。您可以应用的解决方案是将您的第三方依赖项转换为第一方依赖项。您可以通过为该概念引入抽象来做到这一点。实际上,这样做还有其他好处,例如:

  • 更多可维护代码
  • 更好的可测性
  • 摆脱不需要的依赖(CompanyName.SDK 的每个客户端真的需要 Unity 依赖?)

那么,让我们以一个虚构的 .NET Logging 库为例:

CompanyName.SDK.dll 依赖于 .NET Logging 3.0
CompanyName.SomeSolution.Project1 依赖于 .NET Logging 2.0
CompanyName.SomeSolution.Project2 依赖于 .NET Logging 1.0

.NET Logging 版本之间存在重大变化。

可以通过引入ILogger接口(interface)来创建自己的第一方依赖:

public interface ILogger
{
void LogWarning();
void LogError();
void LogInfo();
}

CompanyName.SomeSolution.Project1CompanyName.SomeSolution.Project2 应该使用 ILogger 接口(interface)。它们依赖于ILogger 接口(interface)第一方依赖。现在,您将 .NET Logging 库放在一个地方,执行更新很容易,因为您必须在一个地方进行。版本之间的重大更改也不再是问题,因为使用了一个版本的 .NET Logging 库。

ILogger 接口(interface)的实际实现应该在不同的程序集中,它应该只在您引用 .NET Logging 库的地方。在 CompanyName.SomeSolution.Application 中,在您编写应用程序的地方,您现在应该将 ILogger 抽象映射到具体实现。

我们正在使用这种方法,我们还使用 NuGet 来分发我们的抽象和实现。不幸的是,您自己的包可能会出现版本问题。为避免该问题,请应用 Semantic Versioning在您通过 NuGet 为您的公司部署的包中。如果通过 NuGet 分发的代码库中发生了某些更改,您应该更改通过 NuGet 分发的所有包。例如,我们在本地 NuGet 服务器中有:

  • 领域模型
  • Services.Implementation.SomeFancyMessagingLibrary(引用 DomainModelSomeFancyMessagingLibrary)
  • 还有更多...

此包之间的版本是同步的,如果版本在 DomainModel 中更改,相同的版本在 Services.Implementation.SomeFancyMessagingLibrary 中。如果我们的应用程序需要更新我们的内部包,所有依赖项都会更新到相同的版本。

关于c# - 如何解决 NuGet 依赖 hell ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32739610/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com