CoreCLR 如何解决项目依赖?

问题描述

最近,我正在开发一种工具,用于验证给定的二进制文件是否可以在运行时加载所需的依赖项,对于 .NET Framework 二进制文件,依赖项的解析非常简单,如前面提到的 here。 对于 .NET Core,我仍然对 CoreCLR 定位和加载程序集的方式感到困惑。 据我所知,CoreCLR 在三个不同的地方搜索:

  • 应用程序基目录
  • 共享目录
  • Nuget 缓存

解析过程依赖于三个Json文件的存在:

  • *.runtimeconfig.json 文件,指定应用程序依赖的 .NET Core 版本

{
  "runtimeOptions": {
    "tfm": "netcoreapp3.1","framework": {
      "name": "Microsoft.NETCore.App","version": "3.1.0"
    }
  }
}

  • *.runtimeconfig.dev.json 包含额外的探测路径

{
  "runtimeOptions": {
    "additionalProbingPaths": [
      "C:\\Users\\yjirari\\.dotnet\\store\\|arch|\\|tfm|","C:\\Users\\yjirari\\.nuget\\packages"
    ]
  }
}

  • *.deps.json 列出应用程序的依赖项及其到 Nuget 缓存的相对路径

{
  "runtimeTarget": {
    "name": ".NETCoreApp,Version=v3.1","signature": ""
  },"compilationOptions": {},"targets": {
    ".NETCoreApp,Version=v3.1": {
      "ConsoleApp1/1.0.0": {
        "dependencies": {
          "Newtonsoft.Json": "12.0.1"
        },"runtime": {
          "ConsoleApp1.dll": {}
        }
      },"Newtonsoft.Json/12.0.1": {
        "runtime": {
          "lib/netstandard2.0/Newtonsoft.Json.dll": {
            "assemblyVersion": "12.0.0.0","fileVersion": "12.0.1.25517"
          }
        }
      }
    }
  },"libraries": {
    "ConsoleApp1/1.0.0": {
      "type": "project","serviceable": false,"sha512": ""
    },"Newtonsoft.Json/12.0.1": {
      "type": "package","serviceable": true,"sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==","path": "newtonsoft.json/12.0.1","hashPath": "newtonsoft.json.12.0.1.nupkg.sha512"
    }
  }
}

*.runtimeconfig.json 的目的非常明显,它允许运行时知道应用程序是针对哪个 .NET Core 版本构建的。

对于 *.runtimeconfig.dev.json 是添加 Nuget 缓存和其他目录作为额外的探测目录 但是对于 .deps,我仍然对其目标感到困惑。

为了阐明 .deps 的作用,我使用依赖于 Newtonsoft.Json v 12.0.1 的控制台项目做了一个小实验。

主要有两种情况:

  • 当 bin 文件夹中存在 .deps 时:

如果 bin 中也存在相同或更高版本(例如 v12、v13)的 Newtonsoft.Json,则应用程序正常执行。 否则 Newtonsoft.Json 从 Nuget 缓存加载。

  • 当 .deps 不存在时:

如果bin中也存在相同或更高版本的Newtonsoft.Json,则应用程序正常执行。 否则引发 FileLoadException

结论:

我从我的实验结果得出结论:

  • 如果依赖项存在于具有相同版本的 bin 文件夹中 或更高的依赖项被加载。
  • .deps 的作用只有在依赖不存在的情况下才会出现 bin 文件夹,这有助于使用 Nuget 缓存加载依赖项 *.runtimeconfig.dev.json 中 Nuget 缓存的路径连接到 .deps 中指定的相对路径。

我的问题如下:

  • 为什么 CoreClr 使用项目引用的上级版本加载依赖项?
  • *.deps 文件在解析依赖项时是否有任何作用,而不是在 Nuget缓存?
  • CoreCLR 是否在搜索依赖项之前解析 .deps?

我看到了这两个关于 CoreCLR 解析的文档,但我对 .deps 的作用没有了解太多。

https://github.com/dotnet/cli/blob/v2.0.0/Documentation/specs/corehost.md https://docs.microsoft.com/en-us/dotnet/core/dependency-loading/default-probing

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...