nuget引用的library藏哪了?
引言
我们都知道, dotnet core的命令行工具运行dotnet restore 会利用nuget获取项目中的依赖项和工具. 上一篇文章dotnet core 使用 MongoDB 进行高性能Nosql数据库操作中, 我引用了MongoDB的驱动库, 但是restore之后, 虽然一切运转正常, 我却产生了迷惑. 以前引用的dll文件默认都会在项目路径中或是在system32中. 找遍了项目文件, 与MongoDB相关的只找到project.json文件中的一句淡淡的引用.
![](https://img.haomeiwen.com/i3065132/4398c230f536a882.png)
不信找不到你丫的!
通过我不屑的努(sou)力(suo), 终于找到了引用文件的存储位置.
![](https://img.haomeiwen.com/i3065132/99fc35320a0fffb8.png)
小样, 这也能难倒小爷?
![](https://img.haomeiwen.com/i3065132/3da59018cfb6049e.png)
restore命令干了什么?
怀着一个操碎了的心, 我心里打出无数个问号, restore命令到底都干了什么吗?
好吧, 翻源码, 打开dotnet core cli的源码, 很容易就找到了restore命令的代码文件.
public static int Restore(IEnumerable<string> args)
{
var prefixArgs = new List<string>();
if (!args.Any(s => s.Equals("--verbosity", StringComparison.OrdinalIgnoreCase) || s.Equals("-v", StringComparison.OrdinalIgnoreCase)))
{
prefixArgs.Add("--verbosity");
prefixArgs.Add("minimal");
}
prefixArgs.Add("restore");
var nugetApp = new NuGetForwardingApp(Enumerable.Concat(prefixArgs, args));
// setting NUGET_XPROJ_WRITE_TARGETS will tell nuget restore to install .props and .targets files
// coming from NuGet packages
const string nugetXProjWriteTargets = "NUGET_XPROJ_WRITE_TARGETS";
bool setXProjWriteTargets = Environment.GetEnvironmentVariable(nugetXProjWriteTargets) == null;
if (setXProjWriteTargets)
{
nugetApp.WithEnvironmentVariable(nugetXProjWriteTargets, "true");
}
return nugetApp.Execute();
}
通读了一遍, 发现只是一些参数处理, 对于我的问题, 并没有什么卵用.
![](https://img.haomeiwen.com/i3065132/d08af986894cd013.png)
不过至少我找到了它 NuGetForwardingApp , 就是它隐藏了真正干活的家伙, 接着追, 找到了真正的幕后黑手 NuGet.CommandLine.XPlat.dll 就是它, 其实就是nuget client的dotnet core 版本. 好吧, clone 代码, 接着翻. 顺便说一下, nuget的源码在https://github.com/NuGet?page=1, 有兴趣的童鞋自行获取.
通过我的不屑努力, 终于在一周之后找到了实际的逻辑代码.
![](https://img.haomeiwen.com/i3065132/ded0977cf69d1f7e.png)
代码700多行, 贴这肯定有人说我凑字, 我才不上当:-) 说下路径吧, 在nuget.client项目下的 nuget.core->nuget.commands->RestoreCommand->RestoreCommand.cs
具体的逻辑也很简单. 如官方文档所言, restore会获取依赖的文件和工具, 所以有两个函数ExecuteRestoreAsync和ExecuteToolRestoresAsync
在ProjectRestoreCommand.TryRestore中, 首先根据project.json文件, 处理Framework的支持
foreach (var pair in runtimesByFramework)
{
_logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_RestoringPackages, pair.Key.DotNetFrameworkName));
frameworkTasks.Add(WalkDependenciesAsync(projectRange,
pair.Key,
remoteWalker,
context,
token: token));
}
生成项目依赖库的图
foreach (var graph in graphs)
{
// Get the runtime graph for this specific tfm graph
var runtimeGraph = GetRuntimeGraph(graph, localRepositories);
var runtimeIds = runtimesByFramework[graph.Framework];
// Merge all runtimes for the output
allRuntimes = RuntimeGraph.Merge(allRuntimes, runtimeGraph);
runtimeTasks.Add(WalkRuntimeDependenciesAsync(projectRange,
graph,
runtimeIds.Where(rid => !string.IsNullOrEmpty(rid)),
remoteWalker,
context,
runtimeGraph,
token: token));
}
foreach (var runtimeSpecificGraph in (await Task.WhenAll(runtimeTasks)).SelectMany(g => g))
{
runtimeGraphs.Add(runtimeSpecificGraph);
}
根据生成的图安装相应的依赖文件
// Install runtime-specific packages
await InstallPackagesAsync(runtimeGraphs,
allInstalledPackages,
token);
好了, 今天就到这, 有什么问题欢迎讨论.
什么? 开始的问题还没解决?
![](https://img.haomeiwen.com/i3065132/dc8280c2168b0844.png)