我想使用Visual Studio中的“引用路径”设置覆盖对dll的nuget包引用。这似乎不起作用。
因此,到目前为止,我删除了nuget包,并将引用添加为dll。但这恰好在您可以使用“引用路径”设置覆盖DLL的时候。
“引用路径”设置是否也应该覆盖nuget包引用?还是我错过了什么?
答案 0 :(得分:0)
“为我工作”
这就是我的测试方式。请注意,正如我在对该问题的评论中所写的那样,项目属性页“参考路径”仅适用于传统项目,而不适用于SDK样式的项目。
我创建了一个控制台应用,使用Dapper
添加了Newtonsoft.Json
和packages.config
软件包,并将我的program.cs
更改为:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace ReferencePathTest
{
class Program
{
static void Main(string[] args)
{
var data = new List<int>() { Dapper.DbString.DefaultLength };
Console.WriteLine(JsonConvert.SerializeObject(data));
}
}
}
运行它时,我的程序输出[4000]
。
接下来,我创建了一个名为Dapper
的类库,将AssemblyReference.cs
文件更改为将两个版本号都设置为1.60.0.0
,然后将c#文件更改为:
namespace Dapper
{
public class DbString
{
public static int DefaultLength => -1;
}
}
我还创建了另一个名为Newtonsoft.Json
的类库,将程序集版本更改为12.0.0.0
,并将c#文件内容更改为:
namespace Newtonsoft.Json
{
public class JsonConvert
{
public string SerializeObject(object o)
{
return "i'm a hacker";
}
}
}
编译两个类库,将程序集复制到目录,然后将该目录添加到引用路径列表中。重建控制台应用程序并运行它,现在我看到[-1]
。那么,为什么要使用我的自定义dapper.dll而不使用我的自定义newtonsoft.json?
打开“开发人员命令提示符”,cd到控制台应用程序目录并运行msbuild -bl -t:rebuild
,然后在MSBuild Structured Log Viewer中打开msbuild.binlog
。我在参考路径中搜索了一个dll的完整路径,并在ResolveAssemblyReference
任务的结果中找到了它。扩展树中一些有趣的节点,这是我看到的:
因此,我们可以看到它选择了我的dapper.dll,并考虑了我的newtonsoft.json.dll,但是完整的消息被删减了。将其复制到剪贴板并粘贴到文本编辑器中,我可以看到完整的消息:
Considered "C:\Users\zivkan\source\repos\ReferencePathTest\ReferencePathTest\..\ReferencePath\Newtonsoft.Json.dll",
but its name "Newtonsoft.Json, Version = 12.0.0.0, Culture=neutral, PublicKeyToken=null"
didn't match the expected name "Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed".
好,因此NuGet包中的Newtonsoft.Json.dll是强名称签名的,而Dapper.dll没有强符号签名,但是编译器如何知道?好吧,看看您的csproj:
<Reference Include="Dapper, Version=1.60.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapper.1.60.6\lib\net451\Dapper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
因此,当您安装软件包时,NuGet进行资产选择,然后告诉项目系统使用程序集全名为csproj添加引用。由于Dapper.dll不是强名称签名,因此我们可以简单地创建一个自定义Dapper.dll,编译器或运行时将使用该自定义Dapper.dll,而不是软件包中的那个。但是,由于Newtonsoft.Json.dll是强名称签名的,因此,我可以欺骗编译器或运行时加载自定义版本的唯一方法是,如果我可以创建一个公钥与Newtonsoft.Json的真实公钥匹配的证书,然后进行签名我带有该证书的自定义dll。
在回答的顶部,您可能已经注意到我写了使用packages.config
向我的控制台应用添加程序包引用的信息。这很重要,因为如果您改用PackageReference
,则.NET构建目标和任务不会以相同的方式进行程序集解析,并且不会使用引用路径。