nuget引用的library藏哪了?

引言

我们都知道, dotnet core的命令行工具运行dotnet restore 会利用nuget获取项目中的依赖项和工具. 上一篇文章dotnet core 使用 MongoDB 进行高性能Nosql数据库操作中, 我引用了MongoDB的驱动库, 但是restore之后, 虽然一切运转正常, 我却产生了迷惑. 以前引用的dll文件默认都会在项目路径中或是在system32中. 找遍了项目文件, 与MongoDB相关的只找到project.json文件中的一句淡淡的引用.

不信找不到你丫的!

通过我不屑的努(sou)力(suo), 终于找到了引用文件的存储位置.

nuget引用的library藏哪了?_第1张图片

小样, 这也能难倒小爷?

restore命令干了什么?

怀着一个操碎了的心, 我心里打出无数个问号, restore命令到底都干了什么吗?
好吧, 翻源码, 打开dotnet core cli的源码, 很容易就找到了restore命令的代码文件.

    public static int Restore(IEnumerable args)
    {
        var prefixArgs = new List();
        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();
    }

通读了一遍, 发现只是一些参数处理, 对于我的问题, 并没有什么卵用.

不过至少我找到了它 NuGetForwardingApp , 就是它隐藏了真正干活的家伙, 接着追, 找到了真正的幕后黑手 NuGet.CommandLine.XPlat.dll 就是它, 其实就是nuget client的dotnet core 版本. 好吧, clone 代码, 接着翻. 顺便说一下, nuget的源码在https://github.com/NuGet?page=1, 有兴趣的童鞋自行获取.
通过我的不屑努力, 终于在一周之后找到了实际的逻辑代码.

nuget引用的library藏哪了?_第2张图片

代码700多行, 贴这肯定有人说我凑字, 我才不上当:-) 说下路径吧, 在nuget.client项目下的 nuget.core->nuget.commands->RestoreCommand->RestoreCommand.cs
具体的逻辑也很简单. 如官方文档所言, restore会获取依赖的文件和工具, 所以有两个函数ExecuteRestoreAsyncExecuteToolRestoresAsync
在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);

好了, 今天就到这, 有什么问题欢迎讨论.

什么? 开始的问题还没解决?

你可能感兴趣的:(nuget引用的library藏哪了?)