为什么有时我需要添加 Nuget 依赖项,即使我的项目没有直接使用它们?

Why do I sometimes need to to add Nuget dependencies even if they're not used directly by my project?

抱歉标题含糊不清,但我真的不知道如何简洁地表达它。

这是我的问题:我有一个 .NET Framework C# 解决方案,其中有 2 个项目:

Project A中,我有一个这样的方法:

public class FooClass {
    public static void Foo(){
        //does something with a class from referenced Nuget package "NP"
        NP.BarClass.Bar();
        return;
    }
}

Project B中,我调用上面提到的方法,像这样:

public static void main(){
    FooClass.Foo();
}

但是,这会产生以下编译器错误:

The type 'BarClass' is defined in an assembly that is not referenced. You must add a reference to assembly 'NP, Version=X.X.X.X, Culture=neutral, PublicKeyToken=xxxxxxxxxxx'

根据编译器的建议,解决方案是在项目 B 中也添加对 Nuget 包 NP 的引用。当我这样做时,一切都按预期工作。

我的问题是:

编辑:我已经在 self-contained 示例中重现了该问题,请参阅 here

Why does this happen only with certain Nuget packages? I've been working with C# for a while now, and this doesn't happen with all packages, only some of them.

由于你的问题比较复杂,我们这边无法进行整体测试,或许你可以按照以下方式进行:

实际上,确实有可能你的VS Framework版本包引用格式 特定的 nuget 包

class库项目中安装了一些特定的nuget包,但是当其他项目引用class库时,某些特定包的内容会与旧的框架版本冲突VS,所以还是需要引用main 项目,添加这个依赖才能识别。这只是一些特殊包和框架版本的问题。

还有一个就像zivkan说的,包管理格式要保持一致(Tools-->Options-->Nuget Package Manager-->General-->Package Management),防止管理格式不同造成的冲突。您应该确保项目 A 的输出文件(包括 NP)在项目 B 的输出文件中。

Why does this happen at all? Since my project (Project B) is not directly referencing any types or methods from package NP, why do I have to include it explicitly? Isn't it enough that it's included in Project A, the one that uses it?

我假设您使用旧的 VS 版本 (<=VS2017) 创建此类项目。

一般,你真的不需要在主项目(项目B)中包含这些。

实际上,在VS2017更早的中,形式为Project Reference,确实存在一个问题,即class库项目中依赖的nuget及其文件会在引用它的项目中丢失。 幸运的是,这个问题已经在vs2019中修复了

所以如果你的情况是我说的,我建议你可以使用the latest VS2019

在较旧的 VS 版本中,使用您的解决方案--> 在项目 B 中添加 nuget。

在我这边用 VS2019,我没有遇到同样的错误。

编辑:我已经重现了问题 here

好吧,经过进一步的尝试和错误,我终于找到了问题的根源,让我告诉你:这很奇怪,至少在我看来是这样。

因此,这似乎只在某些情况下发生的原因是因为似乎有进一步的要求才能发生这种情况。特别是,您必须有一个 重载方法,其参数数量与 returns 或接受相关 nuget 包中的类型作为参数.

在我的例子中,ProjectA 中的 FooClass 是这样的:

public class FooClass
{
    public static void Foo(string x)
    {
        //Do something
        return;
    }

    public static void Foo(ClassFromNugetPackage np)
    {
        //Do something
        return;
    }
}

现在,在 ProjectB 中,我只调用了第一个方法,即带有 string 参数的方法,但那给了我错误,即使项目没有直接引用任何class 来自 nuget 包。

但是,如果我重命名第二个方法,那么它就不再是重载了,就像这样:

public class FooClass
{
    public static void Foo(string x)
    {
        //Do something
        return;
    }

    public static void Bar(ClassFromNugetPackage np) //Renamed method
    {
        //Do something
        return;
    }
}

问题消失了!

如果有人能告诉我这背后的逻辑,我会很高兴。我的意思是,方法重载是在编译时解决的,对吧?编译器应该知道我正在调用的方法版本不包含 nuget 包中的 return/accept 东西……那为什么会出错?