我发现了一些有关.NET Core SDK /运行时/工具版本控制困难的有趣文章,例如:
但是我仍然不知道如何在实践中处理所有这些:
哦,还有一个:
答案 0 :(得分:15)
首先,让我们看一下通过dotnet yourapp.dll
运行可移植.NET Core应用程序时会发生什么:
dotnet.exe
)从hostfxr
旁边的host\fxr\
下方的文件夹中加载主机框架解析程序(dotnet.exe
)的一个版本。yourapp.runtimeconfig.json
(如果在使用dotnet exec
时配置了其他文件,则会查找您要定位的框架)。这会提取框架名称(Microsoft.NETCore.App
)和版本(例如1.1.0
)。shared\Microsoft.NETCore.App
文件夹(基于框架名称)。yourapp.runtimeconfig.json
中的可用版本和框架版本,它确定要使用的版本。或者它可能会决定错误并抱怨所需的版本不可用。
目前(.NET Core 1.0),框架解析器将使用可用于runtimeconfig.json
中指定的主要版本和次要版本的最新补丁版本,但不会低于runtimeconfig.json
指定的版本。例如。如果运行时配置指定1.1.2
,则将使用1.1.1
运行时,但如果只有1.1.0
可用,则会记录错误。在次要版本中也没有版本前滚。因此,如果只安装了1.0.0
,则运行时配置设置为1.1.*
的应用程序将触发错误。
对于.NET Core 2.0,如果未找到匹配的次要版本,则计划进行次要版本前滚 - 如果安装了1.0.5
和1.1.2
运行时,则运行时配置为{的应用程序{1}}将在1.0.4
运行时运行。如果仅安装了1.0.5
,则会在1.1.2
上运行相同的应用。如果仅安装1.1.2
,则无法运行相同的应用。有关此更改的详细信息和讨论,请参阅GitHub issue for .NET Core 2+ Version Binding。
让我们看一下运行时配置中的值来自何处。当您定位框架2.0.0
时,您使用的工具将确定:
netcoreapp1.1
在csproj文件中,要使用的框架版本由属性
确定yourapp.runtimeconfig.json
如果未指定此值,则工具将使用它知道的最新版本 对于.NET Core 1.0和1.1。
对于.NET Core 2.0,可移植应用程序默认使用补丁版本<RuntimeFrameworkVersion>1.1.2</RuntimeFrameworkVersion>
,自包含应用程序将使用工具知道的最新版本。之所以进行此更改,是因为工具(CLI&#34; SDK&#34; / Visual Studio)更新和运行时更新已同时发布,因此应用程序默认需要在目标系统上安装新的运行时。如果未安装该运行时,则会发生错误。如果托管人需要几天的时间才能赶上测试和安装更新,那就太糟糕了。通过明确设置0
,仍然可以强制执行/需要该版本。
关于包:1. *工具使用的包是元包。因此,引用<RuntimeFrameworkVersion>
或Microsoft.NETCore.App
会引入许多其他NuGet包。 .NET Core 2.0和.NET Standard 2.0不再是这种情况 - 软件包是扁平的,包含您需要的所有内容。此外,当您创建NuGet包时,这些包将不再是生成的包的依赖项。它们仅用于编译引用,但NETStandard.Library
知道要为自包含应用程序引入哪些附加包。
以前,使用Microsoft.NETCore.App
版本NETStandard.Library
构建的库会导致消耗.NET Core 1.0应用程序包含大量已更新的DLL文件,这些文件实际上是1.6.1
的一部分。我不知道这是否意味着LTS策略将涵盖或不涵盖最终使用这些DLL的应用程序。并且很难看出它们属于哪个.NET Core版本,因为它们源自的软件包版本通常是.NET Core 1.1
,4.0.*
和4.1.*
。
对于ASP.NET核心软件包,它更容易,因为它们的版本为4.3.*
和1.0.*
,因此您可以看到哪些&#34;分支&#34;它们起源于您,并且您可以通过在csproj文件中指定NuGet包来更好地控制所使用的版本。
回顾一下,让我们回到原来的问题:
- 给定一个具有许多.Net Core依赖项的项目。如何确定需要在哪个版本的运行时上可用 最终用户机器?
醇>
这里真正的依赖是将1.1.*
的哪个版本写入Microsoft.NETCore.App
文件。必须安装相同的主要和次要编号以及相同或更高的修补程序编号的版本,将使用最新的修补程序版本。安装.NET Core 2.0解析程序时,将使用具有相同主编号的最高版本,但将优先使用相同主编号和次编号的版本。
如果仅安装了具有较新主要版本的运行时,则无法在目标系统上运行该应用程序。 (例如yourapp.runtimeconfig.json
app和1.0.5
运行时)
- 运行时版本是否需要完全匹配,或者最终用户计算机上安装的运行时是否比所需版本更新?
醇>
运行时配置的版本是最低限度的。有关选择正确版本的较新运行时的信息,请参见上文。
- 我想说我想坚持运行时的某些LTS版本。如何确定我需要引用的软件包的版本?怎么样 我可以确保没有引用更新的包吗?
醇>
2.0.0
的版本将自动从目标框架中推断出来(例如Microsoft.NETCore.App
=&gt; netcoreapp1.0
,修补程序版本取决于您使用的工具版本)。要覆盖版本,请按上面的说明设置1.0.*
属性。
如果传递新的NuGet包,例如通过从.NET Core 1.0应用程序中消耗Newtonsoft.Json 10.0.0(请参阅GitHub issue),可能会将一些额外的DLL添加到项目的输出中。这些是运行时的一部分的较新版本的DLL,但是会覆盖运行时的版本。
如果您确实希望确保不使用任何FTS版本,则需要在csproj文件中明确引用所有这些软件包,以便NuGet降级所用软件包的版本(和发出包降级警告)。
这里的问题是,在1.0和1.1软件包中没有修复问题的情况。如果将来支持1.0和2.0但1.1不再是问题,我们将不得不看看如何处理这个问题。 (尽管社区肯定会有压力/要求发布更新的1.1版本,即使微软的支持不包括在内)。
如果您使用<RuntimeFrameworkVersion>
或更高版本,那么这些实施包将从您应用的依赖关系图中删除,并在部署时不再予以考虑。这是冲突解决逻辑的一部分,它知道新的扁平包包含与各个包相同的DLL文件。
- 一旦我知道最终用户计算机上需要哪个运行时版本,我如何(以编程方式)确定该版本的 运行时(或更新的,向后兼容的)可用吗?
醇>
2.0
旁边的shared\Microsoft.NETCore.App
子文件夹,并实现主机使用的相同逻辑。dotnet.exe
旁边hostfxr.dll
中最新host\fxr
的原生代码。但这样做相当复杂。